装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象
装饰模式 Decorator
问题:
You want to add behavior or state to individual objects at run-time. Inheritance is not feasible because it is static and applies to an entire class..
意图:
- Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
- Client-specified embellishment of a core object by recursively wrapping it.
- Wrapping a gift, putting it in a box, and wrapping the box.
代码
例:在游戏里面相当多,99%的游戏系统都可以给角色换装,但不一定彩用了装饰模式,如果用了的话,后续进行扩展(时装)等就比较简单了,这里来个demo简单的给车换装备。
代码1:包含两个部件的车,以及它的“裸装”(进入游戏送的)
package com.xdnote.DesignPattern.structural.decorator;
public abstract class Car {
public String body ;
public String engine ;
public abstract void setBody(String car);
public abstract void setEngine(String car);
public void show() {
System.out.println("最终结果:");
System.out.println(this.body);
System.out.println(this.engine);
}
}
public class DefaultCar extends Car {
public DefaultCar(){
this.setBody("普通车身");
this.setEngine("普通引擎");
}
@Override
public void setBody(String body) {
System.out.println("装备普通车身");
this.body = body;
}
@Override
public void setEngine(String engine) {
System.out.println("装备普通引擎");
this.engine = engine;
}
}
代码二:装饰车,即是车,也是零件。(可换装备)
/**
* @author xdnote.com
* 装饰类,装饰模式的核心.继承并实现主类
* 注意,这里我把这个类也定为抽象类,因为具体的装饰任务应该都由子类去完成.这里定义了一个抽象方法decorator
*
* */
public abstract class DecoratorCar extends Car{
/**
* 构造方法,参数为想要被装饰的对象(车)
* */
public DecoratorCar(Car car) {
this.body = car.body;
this.engine = car.engine;
this.decorator();
}
/**
* 装饰(抽象)方法,由具体子类实现
* */
public abstract void decorator();
@Override
public void setBody(String body) {
this.body = body;
}
@Override
public void setEngine(String engine) {
this.engine = engine;
}
}
代码三:不做说明
public class BodyLv1 extends DecoratorCar{
public BodyLv1(Car car) {
super(car);
}
@Override
public void decorator(){
System.out.println("装备1级车身");
this.setBody("1级车身");
}
}
public class BodyLv2 extends DecoratorCar {
public BodyLv2(Car car) {
super(car);
}
@Override
public void decorator(){
System.out.println("装备2级车身");
this.setBody("2级车身");
}
}
public class BodyLv3 extends DecoratorCar{
public BodyLv3(Car car) {
super(car);
}
@Override
public void decorator(){
System.out.println("装备3级车身");
this.setBody("3级车身");
}
public void setBody(String body){
this. body = body;
System.out.println(">>>>经过3级车身改装,外观牛B了");
}
}
public class EngineLv1 extends DecoratorCar {
public EngineLv1(Car car) {
super(car);
}
@Override
public void decorator(){
System.out.println("装备1级引擎");
this.setEngine("1级引擎");
}
}
public class EngineLv2 extends DecoratorCar {
public EngineLv2(Car car) {
super(car);
}
@Override
public void decorator(){
System.out.println("装备2级引擎");
this.setEngine("2级引擎");
}
public void setEngine(String engine){
this.engine = engine;
System.out.println(">>>>经过2级引擎改装,性能加强了");
}
}
public class EngineLv3 extends DecoratorCar {
public EngineLv3(Car car) {
super(car);
}
@Override
public void decorator(){
System.out.println("装备3级引擎");
this.setEngine("3级引擎");
}
}
代码四:客户端使用
public static void main( String[] args ) {
Car car1 = new DefaultCar();
car1.show();
System.out.println("-------");
Car car2 = new EngineLv1(new DefaultCar());
car2.show();
System.out.println("-------");
Car car3 = new BodyLv2(new EngineLv3(new DefaultCar()));
car3.show();
System.out.println("-------");
Car car4 = new EngineLv3( new BodyLv2( new EngineLv1(new DefaultCar())));
car4.show();
System.out.println("-------");
Car car5 = new BodyLv1(new BodyLv2(new BodyLv3(new EngineLv3(new EngineLv2(new EngineLv1(new DefaultCar()))))));
car5.show();
}
小结
装饰模式 Decorator
- 使用频率:
低
装饰模式相对于组合模式来说,每个点上只有一个对象,使用的场景会多一些,但在Web编程中也是挺少见的。
- 利弊影响:
中
有了这个模式后,安全性可以得到很大保障,特别是对一些热插拔思想的代码很有用。