学习笔记——装饰器模式

装饰器模式(Decorator Pattern)

定义:装饰器模式也叫包装模式,是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案。

属于结构型模式。

适用场景

  1. 用于扩展一个类的功能或给一个类添加附加职责
  2. 动态的给一个对象添加功能,这些功能可以在动态的撤销

通用写法

public abstract class Component {
    /** 
     * 示例方法 
     */  
    public abstract void operation();  
}  

public class ConcreteComponent extends Component {
  
    public void operation() {  
        //相应的功能处理
        System.out.println("处理业务逻辑");
    }  
  
}  

public abstract class Decorator extends Component {
    /** 
     * 持有组件对象 
     */  
    protected Component component;  
  
    /** 
     * 构造方法,传入组件对象 
     * @param component 组件对象 
     */  
    public Decorator(Component component) {  
        this.component = component;  
    }  
  
    public void operation() {  
        //转发请求给组件对象,可以在转发前后执行一些附加动作  
        component.operation();  
    }  
  
  
}  

public class ConcreteDecoratorA extends Decorator {
       public ConcreteDecoratorA(Component component) {  
            super(component);  
   }  
       private void operationFirst(){ } //在调用父类的operation方法之前需要执行的操作  
       private void operationLast(){ } //在调用父类的operation方法之后需要执行的操作  
       public void operation() {  
           //调用父类的方法,可以在调用前后执行一些附加动作  
           operationFirst(); //添加的功能  
           super.operation();  //这里可以选择性的调用父类的方法,如果不调用则相当于完全改写了方法,实现了新的功能  
           operationLast(); //添加的功能  
   }  
}  

public class ConcreteDecoratorB extends Decorator {
       public ConcreteDecoratorB(Component component) {
            super(component);  
   }  
       private void operationFirst(){ } //在调用父类的operation方法之前需要执行的操作  
       private void operationLast(){ } //在调用父类的operation方法之后需要执行的操作  
       public void operation() {  
           //调用父类的方法,可以在调用前后执行一些附加动作  
           operationFirst(); //添加的功能  
           super.operation();  //这里可以选择性的调用父类的方法,如果不调用则相当于完全改写了方法,实现了新的功能  
           operationLast(); //添加的功能  
   }  
}  

public class Client{
    public static void main(String[] args){
        Component c1 = new ConcreteComponent (); //首先创建需要被装饰的原始对象(即要被装饰的对象)
        Decorator decoratorA = new ConcreteDecoratorA(c1); //给对象透明的增加功能A并调用
        decoratorA .operation();

        Decorator decoratorB = new ConcreteDecoratorB(c1); //给对象透明的增加功能B并调用
        decoratorB .operation();
        Decorator decoratorBandA = new ConcreteDecoratorB(decoratorA);//装饰器也可以装饰具体的装饰对象,此时相当于给对象在增加A的功能基础上在添加功能B
        decoratorBandA.operation();
    }
}  

一个简单的装饰器的例子

public abstract class Battercake {

    protected abstract String getMsg();

    protected abstract int getPrice();

}

public class BaseBattercake extends Battercake{

    protected String getMsg(){ return "煎饼";}

    public int getPrice(){ return 5;}

}

// 装饰器类
public class BattercakeDecorator extends Battercake{


    private Battercake battercake;

    public BattercakeDecorator(Battercake battercake) {
        this.battercake = battercake;
    }

    protected String getMsg(){ return this.battercake.getMsg();}

    public int getPrice(){ return this.battercake.getPrice();}

}

public class EggDecorator extends BattercakeDecorator{

    public EggDecorator(Battercake battercake) {
        super(battercake);
    }

    protected String getMsg(){ return super.getMsg() + "1个鸡蛋";}

    public int getPrice(){ return super.getPrice() + 1;}

}


public class SauageDecorator extends BattercakeDecorator{

    public SauageDecorator(Battercake battercake) {
        super(battercake);
    }

    protected String getMsg(){ return super.getMsg() + "1根香肠";}

    public int getPrice(){ return super.getPrice() + 2;}

}


public class Test {
    public static void main(String[] args) {


        Battercake battercake;

        battercake = new BaseBattercake();

        battercake = new EggDecorator(battercake);

        battercake = new EggDecorator(battercake);

        battercake = new SauageDecorator(battercake);

        System.out.println(battercake.getMsg() + ",总价" + battercake.getPrice());

    }
}

装饰器模式和代理模式对比

  • 装饰器模式就是一种特殊的代理模式
  • 装饰器模式强调自身的功能扩展
  • 代理模式强调代理过程的控制

装饰器模式的优点

  • 装饰器是继承的有力补充,比继承灵活,不改变原有对象的情况下动态地给一个对象扩展功能,即插即用。
  • 通过使用不同装饰类以及这些装饰类的排列组合,可实现不同效果
  • 装饰器完全遵守开闭原则

装饰器模式的缺点

  • 会增加代码量和类,增加程序的复杂性
  • 动态装饰时,多层装饰时会更复杂

猜你喜欢

转载自blog.csdn.net/weixin_43222122/article/details/108222483