装饰模式
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 + "公里");
}
}
运行结果如下: