设计模式学习-使用go实现装饰模式

装饰器模式

定义

装饰模式:动态的给一些对象添加额外的职责,就增加功能来说,装饰模式比生成子类更灵活。

举个栗子:

我们现在买手机或者电脑,都有基础配置,然后根据我们选择的运行内存的大小,具体的CPU,手机或电脑的价格最终价格就是不一样的。这里就用到装饰模式,定制的内存和CPU对我们的设备进行了装饰作用。

看下结构图

decorator

代码实现

// 基础款 16g运存 10代cpu
type basicPhone struct {
}

func (p *basicPhone) getPrice() int {
	return 2000
}

// 32g运存
type choose32RAMPhone struct {
	phone phone
}

func (r *choose32RAMPhone) getPrice() int {
	price := r.phone.getPrice()
	return price + 500
}

// 11代CPU
type choose11CPUPhone struct {
	phone phone
}

func (r *choose11CPUPhone) getPrice() int {
	price := r.phone.getPrice()
	return price + 1000
}

测试代码

func TestDecorator(t *testing.T) {
	phone := &basicPhone{}

	choose32RAMPhone := &choose32RAMPhone{
		phone: phone,
	}

	orderPhone := &choose11CPUPhone{
		phone: choose32RAMPhone,
	}

	t.Log(orderPhone.getPrice())
}

优点

1、装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用

2、通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果

3、装饰器模式完全遵守开闭原则

装饰器模式主要解决继承关系过于复杂的问题,通过组合来替代继承。它主要的作用是给原始类添加增强功能。这也是判断是否该用装饰器模式的一个重要的依据。除此之外,装饰器模式还有一个特点,那就是可以对原始类嵌套使用多个装饰器。为了满足这个应用场景,在设计的时候,装饰器类需要跟原始类继承相同的抽象类或者接口。

缺点

装饰器模式会增加许多子类,过度使用会增加程序得复杂性。

适用范围

1、扩展一个类的功能。

2、动态增加功能,动态撤销。

装饰器模式和桥接模式的区别

两个模式都是为了解决子类过多问题, 但他们的诱因不同:

1.桥接模式对象自身有,沿着多个维度变化的趋势, 本身不稳定;

2.装饰者模式对象自身非常稳定, 只是为了增加新功能/增强原功能。

参考

【文中代码】https://github.com/boilingfrog/design-pattern-learning/tree/master/装饰器模式
【大话设计模式】https://book.douban.com/subject/2334288/
【极客时间】https://time.geekbang.org/column/intro/100039001
【装饰模式】https://boilingfrog.github.io/2021/11/13/使用go实现装饰模式/#装饰器模式

posted on 2021-11-13 19:00  ZhanLi  阅读(244)  评论(0编辑  收藏  举报