装饰模式(Decorator Pattern)是一种比较常见的模式。
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰着模式相比于代理模式生成子类更为灵活。
装饰模式有以下4个角色:
1.抽象构件角色:该角色用于规范需要装饰的对象(原始对象)
2.具体构件角色:该角色实现抽象构件接口,定义一个需要装饰的原始类。
3.装饰角色:该角色持有一个构件对象的实例,并定义一个与抽象构件接口一致的接口。
4.具体装饰角色:该角色负责对构件对象进行装饰。
例子:
王小华从奔驰4s店购买了一辆E260车,本打算直接送给女朋友,不过他考虑到女朋友方向感不是很好,而且喜欢HelloKitty,所以他打算把刚买的车装饰一下再送过去。他在4S店安装了一个GPS导航系统和行车记录仪,然后又买了一整套HelloKitty坐垫和贴纸,给车做了一个“美容”,让新车看起来比原来更加温馨,除此之外,他还在车的后视玻璃上贴上了一张警示语,标明司机是新手,提醒车辆避让。
在上面的场景中,王小华对爱车的装饰过程类似于设计模式中的装饰模式。
创建汽车接口ICar
package Decorator;
//汽车接口(抽象类构件角色)
public interface ICar {
//车的装配
public void show();
}
奔驰E260汽车BenzE260类实现ICar接口
package Decorator;
//奔驰E260车(裸车,需要装饰)(具体构件)
public class BenzE260 implements ICar {
public void show() {
System.out.println("奔驰E260无导航仪,无行车记录仪,内饰原装......");
}
}
汽车修饰抽象类CarDecorator实现ICar接口
package Decorator;
//汽车装饰(抽象装饰)(装饰角色)
public abstract class CarDecorator implements ICar {
private ICar car = null;
public CarDecorator(ICar car){
this.car = car;
}
public void show() {
this.car.show();
}
}
汽车修饰实现类ConcreteCarDecorator继承
CarDecorator类
package Decorator;
//具体装饰角色
public class ConcreteCarDecorator extends CarDecorator {
public ConcreteCarDecorator(ICar car){
super(car);
}
//给车安装行车记录仪
private void setGrapher(){
System.out.println("安装高清大容量带夜视的行车记录仪......");
}
//给车安装Gps设备
private void setGps(){
System.out.println("安装最顶级的GPS定位导航系统");
}
//给车铺上坐垫并贴上警示语
private void setCushion(){
System.out.println("铺上HelloKitty的坐垫,然后在候车玻璃贴上警示语标签,标明司机是新手");
}
public void show(){
super.show();
this.setGrapher();
this.setGps();
this.setCushion();
}
}
运行结果如下:
奔驰E260无导航仪,无行车记录仪,内饰原装......
安装高清大容量带夜视的行车记录仪......
安装最顶级的GPS定位导航系统
铺上HelloKitty的坐垫,然后在候车玻璃贴上警示语标签,标明司机是新手