【Golang】装饰者模式简单实现

1,861 阅读2分钟

一、前言

在看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)

三、注意事项(一定要看!!!)

  • 使用接口的时候,内嵌接口要用一个实现此接口的结构体赋值
  • 外层结构体中,只能调用内层接口定义的方法。
  • 外层结构体作为接收者,重新定义同名方法可以覆盖内层内嵌结构中定义的方法,并可调用内嵌接口的方法