Go Interface
本质:将接口类型的行为抽象为契约,建立双方共同遵守的约定(解耦)。
定义:尽量定义小接口(方法个数在 1~3 个之间),接口越小,其抽象程度越高,其表示的“契约”职责越单一,同时也易于组合(契合 Go 基于接口的组合思想)。
经验:接受接口,返回结构体(避免使用 any 作为函数参数类型,编译器不会对它做类型安全检查)。
如何设计组合
垂直:使用多个原有类型通过类型嵌入的方式定义新类型。
水平:使用接受接口类型参数的函数或方法。要注意接口分离原则。
如何设计接口
思路:对问题领域进行深入理解,聚焦抽象并发现接口。
技巧:可以先抽象出接口(不需要在意接口大小),再进行接口拆分(在此过程中,关注接口的单一契约职责)。
Adapter Pattern
适配器模式的核心是 Adapter Function Type(用于辅助水平组合),它将一个满足适当函数签名的普通函数显式转换为 Adapter Function Type 的实例(转换后的实例也就是某个接口的实现者)。
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
// Adapter Func Type
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
// 普通函数
func greetings(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Welcome!")
}
func main() {
// greetings 通过 http.HandlerFunc 转换成了 HandlerFunc 类型, 成为
// 了 Handler 接口的一个实现者
http.ListenAndServe(":8080", http.HandlerFunc(greetings))
}