From Now On,Let us begin Design Patterns。
装饰模式
定义
- 保持接口不变的情况下,动态地给一个对象添加一些额外的职责。就增加功能来讲,装饰模式相比生成子类更为灵活。 (Decorator Pattern)Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality.
通用类图:
角色说明:
1. Component抽象构件(必须的)
Component是一个接口或者是抽象类,定义我们最核心的对象,也就是最原始的对象。
2. SomeConcreteComponent具体构件
ConcreteComponent是最核心、最原始、最基本的接口或抽象类的实现,它是要被装饰的目标。
3. Decorator装饰角色
Decorator一般是一个抽象类,用来实现接口或者抽象方法,这里面不一定有抽象的方法,但在它的属性里必然有一个private变量指向Component抽象的构件。
4. ConcreteDecorator
ConcreteDecorator是具体的装饰类,也就是要附加到ConcreteComponent的事物实现。
装饰模式的优点:
装饰类与被装饰类可以独立发展,而不会相互耦合
装饰模式是继承关系的一个替代方案。查看Decorator类,不管装饰多少层,返回的对象还是Component,实现的还是is-a的关系。
装饰模式可以动态地扩展一个实现类的功能,其定义如此
装饰模式的缺点:
尽量减少装饰叠加类的数量,叠加次数越多,系统的复度越高
利用装饰者模式,会造成设计中存在大量的小类,代码不易读
装饰模式的使用场景:
继承是静态的给类增加功能,而装饰是动态的增加功能
当业务变更,冒出新需求时,尤其是一个较大的需求时,可以考虑它
需要扩展一个类的功能,或给一个类增加额外的功能
需要动态地给一个对象增加功能,这些功能可以再动态地撤销
需要为一批兄弟类进行改装或加装功能,首选装饰模式
装饰模式的例子:源自head frist of 设计模式
我们举一个买饮料结账的例子:
类图:
Component抽象类,奶茶抽象类,从饮料下手,将饮料作为一个抽象类:
实现具体的饮料(茉莉花茶和红茶):
调料抽象类,也就是装饰者类:
实现具体装饰者类:(抹茶和奶盖)
奶茶店卖奶茶:
运行结果:
Java中的装饰者模式(java.io类):
Java I/O引出装饰者模式的一个“缺点”:利用装饰者模式,会造成设计中存在大量的小类。