不以静态继承而是用动态组合的方式增加功能
UML 图如下:
ProductDecorator 与 ProductA、ProductB 类别一样都是以 Product interface 实作,并且拥有依照 Product 定义的成员,所以在呼叫operation()
时就可以呼叫成员的operation()
并且再新增额外的功能。
在 golang 中没有继承,所以在现有功能中新增功能其实就是利用 Decorator Pattern,但如果在 java 中,时常使用继承来新增功能,但如果过度使用继承,事实上没有办法重用程序,如下:
PS5 主机 interface 有PS5.StartGPUEngine()
来启动显示晶片,PS5WithCD{}
、PS5WithDigital{}
都会继承此 interface 来实作,但如果这时候要在显示晶片上新增加强功能,就需要在继承一次导致PS5WithCDPlus{}
、PS5WithDigitalPlus{}
的产生,但看我们要做的事情的本质就是「一个」新增加强功能,需要「两个」类是多余的。
UML 图如下:
相关的 code 在Github - go-design-patterns
code 如下:
package main
import "fmt"
type PS5 interface {
StartGPUEngine()
}
type PS5WithCD struct{}
func (p PS5WithCD) StartGPUEngine() {
fmt.Println("start normal gpu engine")
}
type PS5WithDigital struct{}
func (p PS5WithDigital) StartGPUEngine() {
fmt.Println("start normal gpu engine")
}
type PS5MachinePlus struct {
ps5Machine PS5
}
func (p *PS5MachinePlus) SetPS5Machine(ps5 PS5) {
p.ps5Machine = ps5
}
func (p PS5MachinePlus) StartGPUEngine() {
p.ps5Machine.StartGPUEngine()
fmt.Println("start plus plugin")
}
func main() {
ps5MachinePlus := PS5MachinePlus{
ps5Machine: PS5WithCD{}, // or PS5WithDigital{}
}
// ps5MachinePlus.SetPS5Machine(PS5WithDigital{}) // 可以在更换主机
ps5MachinePlus.StartGPUEngine()
}
我们将加强功能定义为一个 struct PS5MachinePlus{}
,这个PS5MachinePlus{}
介面跟PS5WithCD{}
、PS5WithDigital{}
介面都是以PS5
interface 来实作的,所以外部使用者呼叫的时候介面是没有变更的。
PS5MachinePlus{}
拥有ps5Machine{}
,此成员依赖PS5
interface,让 PS5WithCD{}
、PS5WithDigital{}
都可以带入。
PS5MachinePlus{}
在内部实作StartGPUEngine()
时,会使用到ps5Machine{}
,ps5Machine{}
可以在创建 struct 的时候带入,也可以透过 SetPS5Machine()
替换,他是动态带入的,这也让 Decorator Pattern 在 runtime 更加弹性。
<<: D20 - 彭彭的课程# Python 文字档案的读取和储存(2)
>>: Swift 新手-AI/IOT CoreML and TensorFlow
大家好,我是毛毛。ヾ(´∀ ˋ)ノ 废话不多说开始今天的解题Day~ 9. Palindrome N...
用第一次成功建立信心 给予空间、给予适应、不限方式,让团队创造第一次成功 制定了目标、习惯以团队思考...
超连结是建立网页与网页之间的关系,也可以连结到外部网站。a是Anchor的缩写,中文翻译为「锚」,点...
前言 我们紧接着切入 RNN 为架构的编码器-解码器。 在seq2seq之前 RNN Encoder...
今天咱们要来谈的是JavaScript 对象,JavaScript 中的所有事物都是物件:不论是字串...