Decoration

为什么要修饰者模式

动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更加有弹性的替代方案

uml

Decoration_第1张图片
image.png

形式

  1. 修饰者和被修饰者对象有相同的超类型
  2. 可以用一个或者多个修饰者包装一个对象
  3. 修饰者和被修饰者有相同超类,那么可以在任何需要原始对象(被包装的)场合,用被包装过的对象代替它。
  4. 装饰者可以在委托给装饰者包装的行为(getDescription()、getCost())之前或者之后加上自己的行为,来达到特定的目的

代码

  • 组件基类
public abstract class Component {
    protected String description = null;
    
    public String getDescription(){
        return description;
    }

    public abstract double getCost();
}
  • 子类实现类
public class ConcreteComponent1 extends Component{
    public ConcreteComponent1(){
        description = "ConcreteComponent1";
    }
    @Override
    public double getCost() {
        return 0.1;
    }
}
  • 修饰器基类
public abstract class Decorator extends Component{
    public abstract String getDescription();

}
  • 修饰器实现类
public class ConcreteDecorator1 extends Decorator{
    
    private Component component;

    ConcreteDecorator1(Component component){
        this.component = component;
    }
    @Override
    public String getDescription() {
        return component.getDescription() + ",ConcreteDecorator1";
    }

    @Override
    public double getCost() {
        return component.getCost() + 1;
    }
}
  • 测试类
public class Test {
    public static void main(String[] args) {
        Component component = new ConcreteComponent1();
        Component d1 = new ConcreteDecorator1(component);
        Component d2 = new ConcreteDecorator2(d1);
        System.out.println(d1.getDescription());
        System.out.println(d2.getDescription());
        System.out.println(d1.getCost());
        System.out.println(d2.getCost());
    }
}

结果:
ConcreteComponent1,ConcreteDecorator1
ConcreteComponent1,ConcreteDecorator1,ConcreteDecorator2
1.1
3.1

修饰者模式的优缺点

优点:

  1. 装饰者模式可以提供比继承更多的灵活性

  2. 可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。

  3. 通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。

  4. 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。

缺点:

  1. 会产生很多的小对象,增加了系统的复杂性

  2. 这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。

你可能感兴趣的:(Decoration)