接口组合 #
一、接口组合概述 #
Go通过接口嵌入实现组合,将多个小接口组合成大接口。
二、接口嵌入 #
2.1 基本语法 #
go
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
type ReadWriter interface {
Reader // 嵌入Reader
Writer // 嵌入Writer
}
2.2 等价定义 #
go
type ReadWriter interface {
Read(p []byte) (n int, err error)
Write(p []byte) (n int, err error)
}
2.3 使用示例 #
go
type File struct{}
func (f File) Read(p []byte) (n int, err error) {
return 0, nil
}
func (f File) Write(p []byte) (n int, err error) {
return 0, nil
}
var rw ReadWriter = File{}
三、标准库组合 #
3.1 io包接口 #
go
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
type Closer interface {
Close() error
}
type Seeker interface {
Seek(offset int64, whence int) (int64, error)
}
3.2 组合接口 #
go
type ReadWriter interface {
Reader
Writer
}
type ReadCloser interface {
Reader
Closer
}
type WriteCloser interface {
Writer
Closer
}
type ReadWriteCloser interface {
Reader
Writer
Closer
}
type ReadSeeker interface {
Reader
Seeker
}
type WriteSeeker interface {
Writer
Seeker
}
type ReadWriteSeeker interface {
Reader
Writer
Seeker
}
四、组合的好处 #
4.1 灵活性 #
go
func processReader(r Reader) {
// 只需要Read方法
}
func processWriter(w Writer) {
// 只需要Write方法
}
func processReadWriter(rw ReadWriter) {
// 需要Read和Write方法
}
4.2 可组合性 #
go
func Copy(dst Writer, src Reader) (written int64, err error) {
buf := make([]byte, 32*1024)
for {
nr, er := src.Read(buf)
if nr > 0 {
nw, ew := dst.Write(buf[0:nr])
if nw > 0 {
written += int64(nw)
}
if ew != nil {
err = ew
break
}
}
if er != nil {
err = er
break
}
}
return
}
4.3 解耦 #
go
type Storage interface {
Save(key string, data []byte) error
Load(key string) ([]byte, error)
}
type Cache interface {
Get(key string) ([]byte, bool)
Set(key string, data []byte)
}
type CachedStorage interface {
Storage
Cache
}
五、接口层次 #
5.1 基础接口 #
go
type Sizer interface {
Size() int64
}
type Reader interface {
Read(p []byte) (n int, err error)
}
5.2 组合接口 #
go
type SizedReader interface {
Reader
Sizer
}
5.3 扩展接口 #
go
type AdvancedReader interface {
SizedReader
ReadAt(p []byte, off int64) (n int, err error)
}
六、实际应用 #
6.1 数据库接口 #
go
type Queryer interface {
Query(query string, args ...interface{}) (*Rows, error)
}
type Execer interface {
Exec(query string, args ...interface{}) (Result, error)
}
type QueryExecer interface {
Queryer
Execer
}
type Preparer interface {
Prepare(query string) (*Stmt, error)
}
type DB interface {
QueryExecer
Preparer
Begin() (*Tx, error)
Close() error
}
6.2 HTTP接口 #
go
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
type Middleware func(Handler) Handler
6.3 日志接口 #
go
type Logger interface {
Log(msg string)
}
type LeveledLogger interface {
Logger
Debug(msg string)
Info(msg string)
Warn(msg string)
Error(msg string)
}
type FormattedLogger interface {
LeveledLogger
Printf(format string, args ...interface{})
}
七、接口与结构体组合 #
7.1 结构体嵌入接口 #
go
type Handler struct {
http.Handler
}
func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Println("Before")
h.Handler.ServeHTTP(w, r)
fmt.Println("After")
}
7.2 装饰器模式 #
go
type LoggingHandler struct {
handler http.Handler
logger Logger
}
func (h *LoggingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.logger.Log(r.URL.Path)
h.handler.ServeHTTP(w, r)
}
func WithLogging(h http.Handler, l Logger) http.Handler {
return &LoggingHandler{handler: h, logger: l}
}
八、组合模式 #
8.1 适配器模式 #
go
type LegacyReader interface {
ReadOld() []byte
}
type ReaderAdapter struct {
legacy LegacyReader
}
func (a ReaderAdapter) Read(p []byte) (n int, err error) {
data := a.legacy.ReadOld()
copy(p, data)
return len(data), nil
}
8.2 策略模式 #
go
type SortStrategy interface {
Sort([]int)
}
type QuickSort struct{}
func (s QuickSort) Sort(arr []int) {
// 快速排序实现
}
type MergeSort struct{}
func (s MergeSort) Sort(arr []int) {
// 归并排序实现
}
type Sorter struct {
strategy SortStrategy
}
func (s *Sorter) SetStrategy(strategy SortStrategy) {
s.strategy = strategy
}
func (s *Sorter) Sort(arr []int) {
s.strategy.Sort(arr)
}
九、最佳实践 #
9.1 小接口优先 #
go
// 好
type Reader interface {
Read(p []byte) (n int, err error)
}
// 避免
type BigInterface interface {
Read(p []byte) (n int, err error)
Write(p []byte) (n int, err error)
Close() error
Flush() error
}
9.2 组合而非继承 #
go
// 好:组合
type ReadWriter interface {
Reader
Writer
}
// 避免:大接口
type ReadWriter interface {
Read(p []byte) (n int, err error)
Write(p []byte) (n int, err error)
// 更多方法...
}
9.3 接口隔离 #
go
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
type Closer interface {
Close() error
}
// 按需组合
type ReadCloser interface {
Reader
Closer
}
十、总结 #
接口组合要点:
| 特性 | 说明 |
|---|---|
| 嵌入 | 接口嵌入接口 |
| 组合 | 组合多个小接口 |
| 灵活性 | 按需组合接口 |
| 解耦 | 降低耦合度 |
关键点:
- 接口嵌入:将小接口组合成大接口
- 标准库:io包大量使用接口组合
- 灵活性:按需组合,灵活使用
- 小接口:接口越小越灵活
- 解耦:组合降低耦合度
准备好学习空接口了吗?让我们进入下一章!
最后更新:2026-03-26