上一篇文章写的是代理模式,今天的是和它很相似的一个设计模式–装饰模式。代理模式链接
装饰模式(Decorator Pattern)
装饰模式是一种比较常见的设计模式。旨在动态的给一个对象添加额外的职责。如果只是为了增加功能的话,装饰模式比生成子类的方式更加灵活。
上面这段话说明了一个场景,就是“增加功能”,如果觉得当前的对象满足不了你的需求了。你就可以考虑使用装饰模式。比如汽车对象都是插钥匙打火,现在增加需求了,这插钥匙显示不了逼格了;我们要升级成指纹点火的功能,这样的话,那么这样的话你就可以考虑使用装饰模式了。
基本类图:
ICar:他是我们的核心对象,汽车接口/抽象类、也是最原始的对象,相当于一个汽车图纸。
Car:是核心接口的实现类,也是最原始的具体实现对象。我们需要装饰的就是这个类。他是相当于具体的汽车。
CarDecorate :装饰的角色,一般是抽象类,里面最重要的组成是一个ICar的私有变量。为什么不是Car咱们是面向接口编程吗。
CarDecorate A/B:就是具体的装饰实现类。
基本的类以及类图就是这样,下面看一些具体的代码来实现(对照着类图看代码实现)
public interface ICar {
public void fire();
}
public class Car implements ICar {
@Override
public void fire() {
System.out.println("汽车钥匙点火了。。。");
}
}
public abstract class CarDecorate implements ICar {
private ICar icar = null;
//通过构造函数,传递被修饰者
public CarDecorate(ICar _icar){
this.icar = _icar;
}
//委托给被修饰者执行方法
@Override
public void fire() {
this.icar.fire();
}
}
public class CarDecorateA extends CarDecorate{
public CarDecorateA(ICar _icar) {
super(_icar);
}
//定义自己的修饰方法
private void keyFireA(){
System.out.println("指纹A点火。。。");
}
//重写父类的fire方法
public void fire(){
this.keyFireA();
super.fire();
}
}
public class CarDecorateB extends CarDecorate{
public CarDecorateB(ICar _icar) {
super(_icar);
}
//定义自己的修饰方法
private void keyFireB(){
System.out.println("指纹B点火。。。");
}
//重写父类的fire方法
public void fire(){
this.keyFireB();
super.fire();
}
}
public class Client {
public static void main(String args[]){
ICar icar = new Car();
//第一次修饰
icar = new CarDecorateA(icar);
//第二次修饰
icar = new CarDecorateB(icar);
icar.fire();
}
}
装饰模式的使用场景:
1. 需要扩展一个类的功能,或者给一个类增加附加功能。
2. 需要动态的增加一个功能,并且动态的撤销。就是说当你需要使用的时候增加这个功能,不需要的时候可以撤销这个功能。
3. 需要为一批对象进行改装,就拿上面的汽车例子。已经很多汽车出厂设置了钥匙点火,但是现在要改装成指纹点火,全部重写显然不合适。