装饰模式
1、描述
动态的给对象添加一些额外的职责。在许多设计中,可能需要改进类的某个对象的功能,而不是该类创建的全部对象。
2、使用场景
希望动态的增强类的某个对象的功能,而又不影响到该类的其他对象。eg:我们现在有一个车辆生成线,该生成线生产的汽车加一次油能够行使100公里。但是我们现在要一辆加一次油能够行使150公里的汽车,我们现在不可能去重新造一个生产线,也不能去修改现有的生产线,那我们现在改怎么完成这项工作呢?一种好的解决办法就是利用该生成线生成的汽车,我们对其进行改装,对其加一个邮箱,使其能够行使150公里。
3、模式中的角色
抽象组件(AbstractComponent):抽象组件是一个抽象类。抽象组件定义了“被封装者”需要进行“装饰”的方法。
具体组件(ConcreteComponent):具体组件是抽象组件的一个子类,具体组件的实例称作“被装饰者”。
装饰(Decorator):装饰也是抽象组件的一个子类,但装饰还包含一个抽象组件声明的变量以及保存“被装饰者”的引用。装饰可以是抽象类也可以是一个非抽象类,如果是非抽象类,那么该类的实例称作“装饰者”。
具体装饰(ConcreteDecorator):具体装饰是装饰的一个非抽象子类,具体装饰的实例称作“装饰者”。
4、类的关系图
5、代码实现
根据上面的例子和类图给出代码实现
抽象组件:car
package org.sunday.decorator; /** * 抽象组件 * @author sunday * 2014-1-7 */ public abstract class Car { public abstract int runDistance(); }
具体组件:ConcreteCar
package org.sunday.decorator; /** * 具体组件 * @author sunday * 2014-1-7 */ public class ConcreteCar extends Car { public final int DISTANCE = 100; @Override public int runDistance() { return DISTANCE; } }
装饰:DecoratorCar
package org.sunday.decorator; /** * 装饰 * @author sunday * 2014-1-7 */ public abstract class DecoratorCar extends Car { protected Car car; public DecoratorCar() {} public DecoratorCar(Car car) { this.car = car; } }
具体装饰:ConcreteDecoratorCar
package org.sunday.decorator; /** * 具体装饰 * @author sunday * 2014-1-7 */ public class ConcreteDecoratorCar extends DecoratorCar { public final int EXT_DISTANCE = 50; public ConcreteDecoratorCar(Car car) { super(car); } @Override public int runDistance() { return this.car.runDistance() + extRunDistance(); } private int extRunDistance() { return EXT_DISTANCE; } }
测试:
package org.sunday.decorator; public class Test { public static void main(String[] args) { Test test = new Test(); Car concreteCar = new ConcreteCar(); test.runDistanceLog(concreteCar); Car concreteDecoratorCar = new ConcreteDecoratorCar(concreteCar); test.runDistanceLog(concreteDecoratorCar); } private void runDistanceLog(Car car) { int distance = car.runDistance(); System.out.println("这辆车能行使:" + distance + "公里"); } }
运行结果如下: