装饰器模式是继承的替代模式,本质上也是通过对象抽象和对象组合的形式完成。装饰器模式也很少用在设计初始阶段,一般在重构或代码扩展阶段。当需要对现有的对象的行为进行增强时使用。
一、装饰器模式
装饰器模式和组合模式放在一起看是有一些相似的,区别在组合模式是对对象的组合且使用阶段是设计阶段,而装饰模式是对对象行为的组合且使用阶段是代码重构或扩展阶段(增强)
二、案例
举个🌰
看过金庸小说的读者都知道,在小说中有一种老江湖都惯用的武器——暗器,暗器顾名思义就是暗中的武器。类似霹雳子、霹雳雷火弹,蔟藜火弹,霹雳毒火弹等等
其中爆炸式暗器都是在霹雳子的基础上演化而来,进一步增大暗器的杀伤力或杀伤范围
咱可以用代码来构思各种霹雳子的演化和组合
首先对霹雳子进行抽象得到爆炸物,可定义该角色为抽象组件
public interface BoomThing {// 获取爆炸物名称String getName();// 爆炸物杀伤力强度int getStrength();}
霹雳子实现该抽象组件,可定义该角色为具体组件
public class PiLiZi implements BoomThing{@Overridepublic String getName() {return "霹雳子";}@Overridepublic int getStrength() {return 10;}
}
上述代码为软件设计中的通用设计(多态),那么当前上述代码已经存在的前提下,如何对具体组件(霹雳子)的能力进行增强呢?
一般情况下可使用继承,但是继承会导致子类的泛滥,所以我们选择装饰器模式。
装饰器模式是继承的替代模式,装饰器模式也很少用在设计初始阶段,一般在重构或代码扩展阶段。当需要对现有的对象的行为进行增强时使用
接下来对霹雳子的行为进行增强,先对霹雳子加一个铁片增加杀伤力
定义抽象装饰器,对装饰器(增强物)抽象
public abstract class AbstractAddStrengthDecorator implements BoomThing{protected BoomThing boomThing;public AbstractAddStrengthDecorator(BoomThing boomThing){this.boomThing = boomThing;}@Overridepublic String getName() {return boomThing.getName();}@Overridepublic int getStrength() {return boomThing.getStrength();}
}
使用铁片增强威力,该角色可为具体装饰器
public class IronSheets extends AbstractAddStrengthDecorator{public IronSheets(BoomThing boomThing) {super(boomThing);}@Overridepublic String getName() {return super.getName() + "加铁片";}@Overridepublic int getStrength() {return super.getStrength() + 20;}
}
使用毒气增强威力,该角色可为具体装饰器
public class PoisonGas extends AbstractAddStrengthDecorator{public PoisonGas(BoomThing boomThing) {super(boomThing);}@Overridepublic String getName() {return super.getName() + "加毒气";}@Overridepublic int getStrength() {return super.getStrength() + 100;}
}
客户端调用
public class TestMain {public static void main(String[] args) {//单个组合装饰IronSheets ironSheets = new IronSheets(new PiLiZi());System.out.println("暗器名称:" + ironSheets.getName() + ",暗器强度:" + ironSheets.getStrength());//多个组合装饰(解决继承子类泛滥问题)PoisonGas poisonGas = new PoisonGas(new IronSheets(new PiLiZi()));System.out.println("暗器名称:" + poisonGas.getName() + ",暗器强度:" + poisonGas.getStrength());}
}
三、总结
装饰器模式通过嵌套包装多个装饰器对象,可以实现多层次的功能增强。每个具体装饰器类都可以选择性地增加新的功能,同时保持对象接口的一致性