一、前言
在看go-kit的时候有用到装饰者模式,简单实现下以此来帮助理解代码。咱就用简单的服务扩展方式来写这个example来给人一种很简单带入业务逻辑的感觉。只在main.go里实现即可。
装饰者模式:向一个现有的对象添加新的功能,同时又不改变其结构。
二、具体实现
首先,声明一个Service接口,作为后续实现的标准
type Service interface {
Do() string
}
接着,声明一个结构体HelloService,同时实现Do方法即实现了接口
type HelloService struct {
str string
}
func (h HelloService) Do() string {
return h.str
}
到这里我们的main()里面调用,在这时就会打印出Hello Word,是不是超简单
func main() {
var srv Service
srv = HelloService{"Hello Word"}
fmt.Println(srv.Do())
}
当然,还没完,以上作为我们的基础功能来打印Hello Word,在此基础上我们要扩展功能,比如我们想再这之前有其他操作同时不去修改原结构体里的Do()方法,同时不增加子类,这时我们就要用到装饰者模式啦~(≧▽≦)/
来!,声明一个结构体叫extendMiddleware,将Service接口内嵌入此结构体,并实现Do()方法在里面调用接口Service里的Do()方法
type extendMiddleware struct {
Service
}
func (e extendMiddleware) Do() string {
fmt.Println("我是扩展功能~")
return e.Service.Do()
}
这时,我们就可以使用了,修改main.go如下
func main() {
var srv Service
srv = HelloService{"Hello Word"}
srv = extendMiddleware{srv}
fmt.Println(srv.Do())
}
到这里就会多打印出一条我是扩展功能~,在不修改原结构体方法的基础上我们扩展了新功能,实现了装饰者模式。
当然这样写也是可以的哦~
type ServiceFunc func(service Service) Service
func EMiddleware() ServiceFunc {
return func(service Service) Service {
return extendMiddleware{service}
}
}
//然后在main里面调用即可
srv = EMiddleware()(srv)
三、注意事项(一定要看!!!)
- 使用接口的时候,内嵌接口要用一个实现此接口的结构体赋值
- 外层结构体中,只能调用内层接口定义的方法。
- 外层结构体作为接收者,重新定义同名方法可以覆盖内层内嵌结构中定义的方法,并可调用内嵌接口的方法