设计模式之装饰模式

只谈情不闲聊 提交于 2019-12-26 02:11:17

装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

结构

装饰模式结构图
装饰模式的主要角色组成:

  • 抽象类/接口(Component):定义最核心的对象,装饰类和被装饰类的基类。
  • 被装饰类(ConcreteComponent):具体构件,通过继承实现Component抽象类中的抽象方法。最核心、最原始、最基本的接口或抽象类的实现。
  • 装饰类(Decorator):实现了Component接口的同时还在内部维护了一个ConcreteComponent的实例,并可以通过构造函数初始化。而Decorator本身,通常采用默认实现,他的存在仅仅是一个声明:我要生产出一些用于装饰的子类了。而其子类才是赋有具体装饰效果的装饰产品类。
  • 具体装饰类(ConcreteDecorator):具体的装饰产品类,每一种装饰产品都具有特定的装饰效果。可以通过构造器声明装饰哪种类型的ConcreteComponent,从而对其进行装饰。

优缺点

优点:

  • 装饰类和被装饰类可以独立发展,而不会相互耦合。它有效地把类的核心职责和装饰功能分开了。
  • 装饰模式是继承关系的一个替代方案。
  • 装饰模式可以动态地扩展一个实现类的功能。

缺点:

  • 多层装饰比较复杂。

代码实现

Component

 public interface Component { 
      void operation();     
}

ConretetComponent

public class ConcreteComponent implements Component {

    @Override
    public void operation() {
        System.out.println("具体对象的操作");
    }
}

Decorator装饰类

public abstract class Decorator implements Component {

    private Component component = null;
    
    public Decorator(Component component) {
        this.component = component;
    }
    
    @Override
    public void operation() {
        if(component != null) {
            this.component.operation();
        }
    }
    
}

ConcreteDecorator具体装饰类

public class ConcreteDecoratorA extends Decorator {

    //定义被修饰者
    public ConcreteDecoratorA(Component component) {
        super(component);
    }
    
    //定义自己的修饰方法
    private void method1() {
        System.out.println("method1 修饰");
    }
    
    @Override
    public void operation() {
        this.method1();
        super.operation();
    }

}

public class ConcreteDecoratorB extends Decorator {

    //定义被修饰者
    public ConcreteDecoratorB(Component component) {
        super(component);
    }
    
    //定义自己的修饰方法
    private void method2() {
        System.out.println("method2 修饰");
    }
    
    @Override
    public void operation() {
        super.operation();
        this.method2();
    }

}

客户端

public class Client {

    public static void main(String[] args) {
        Component component = new ConcreteComponent();
        //第一次修饰
        component = new ConcreteDecoratorA(component);
        //第二次修饰
        component = new ConcreteDecoratorB(component);
        //修饰后运行
        component.operation();
    }
    
}

控制台输出结果:

method1 修饰
具体对象的操作
method2 修饰
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!