1. 装饰器模式概述
- 装饰器模式能够动态地为对象添加功能,基于对象组合的方式,将复杂的功能简单化、分散化,然后在运行期间根据需要进行动态组合。
- 装饰器模式的类图如下:
- 抽象组件(Componet): 定义一个接口或抽象类,具体构件和装饰器都要实现该接口,以便动态添加职责。
- 具体组件(ConcreteComponet): 具体的组件类,实现抽象组件接口。
- 装饰器(Decorator): 装饰器类,实现抽象组件接口,继承基本共能。
- 具体装饰器(ConcreteDecorator): 具体装饰器类,继承装饰器类,添加具体的功能。
- 手抓饼有很多组合,张三家原始的手抓饼就是一张面皮,之后可以根据个人喜好去添加鸡蛋、培根、脆皮、肉松等配料。
- 这时可以将手抓饼定义为抽象接口,创建具体的手抓饼类完成面皮的制作。然后创建装饰器类,具体装饰器分别为鸡蛋、肉松、脆皮、培根等。通过对象组合,可以根据个人喜好添加配料。
2. 装饰器模式的编程实例
- 创建一个接口作为抽象组件。
- 创建一个具体组件类,需要实现抽象组件接口。
- 创建装饰器类,需要实现抽象组件接口,将抽象组件对象作为内部属性,以便进行请求传递。
- 创建多个具体装饰器类,继承装饰器类,通过super关键字传递请求。
- 根据上面对手抓饼的描述,通过装饰器模式实现一个添加了鸡蛋、脆皮的手抓饼和全部都加的哈破话手抓饼。
interface ICake{
void cook();
}
class ZhangsanCake implements ICake{
@Override
public void cook() {
System.out.println("您的手抓饼");
}
}
class DosageDecorator implements ICake{
private ICake cake;
public DosageDecorator(ICake cake){
this.cake=cake;
}
@Override
public void cook() {
cake.cook();
}
}
class EggDDecorator extends DosageDecorator{
public EggDDecorator(ICake cake) {
super(cake);
}
public void cook(){
super.cook();
System.out.println("加鸡蛋");
}
}
class CuipiDDecorator extends DosageDecorator{
public CuipiDDecorator(ICake cake) {
super(cake);
}
public void cook(){
super.cook();
System.out.println("加脆皮");
}
}
class PeigenDDecorator extends DosageDecorator{
public PeigenDDecorator(ICake cake) {
super(cake);
}
public void cook(){
super.cook();
System.out.println("加培根");
}
}
public class DecaratorTest {
public static void main(String[] args){
ICake cake=new ZhangsanCake();
ICake cake1=new EggDDecorator(new CuipiDDecorator(cake));
cake1.cook();
ICake cake2=new PeigenDDecorator(new EggDDecorator(new CuipiDDecorator(cake)));
cake2.cook();
}
}
3. 装饰器模式总结
① 装饰器模式的优缺点
- 优点:
能够更灵活的扩展对象功能: 装饰器模式和继承都是为了扩展对象的功能,但装饰器模式更灵活,根据需要进行动态组合。 - 缺点:
- 装饰器模式会产生比继承关系更多的对象,大量的小对象占据内存,一定程度上影响性能。
- 装饰器模式容易出错,大量的小对象使得错误不易排查。
② 装饰器模式在I/O中的应用
- 抽象组件:InputStream/OutputStream
- 具体组件:FileInputStream/FileOutputStream
- 装饰器:FilterInputStream/FilterOutputStream
- 具体装饰器:BufferedInputStream/BufferedOutputStream
③ 装饰器模式与代理模式的区别
- 装饰器模式可以在不改变接口的前提下,动态组合或新增对象的功能。即新增对象功能
- 代理模式可以在不改变接口的前提下,为对象提供一种代理以控制对该对象的访问。即控制访问。
- 装饰器模式侧重于增强,通过动态组合使对象的功能得到扩展。
- 代理模式侧重于代理,通过代理对象间接访问目标对象,达到访问控制的目的。