设计模式 - 装饰模式(Decorator)

设计模式 - 装饰模式(Decorator)

装饰模式(Decorator)的概念

  • 装饰模式又叫包装模式。
  • 装饰模式以对客户端透明的方式扩展对象的功能,对象功能包括属性方法等,相比继承关系是类的扩展。
  • 装饰模式以对客户端透明的方式动态的给一个对象附加更多的功能,客户端不会感觉到对象在装饰前和装饰后有什么不同。
  • 装饰模式可以在不创建更多子类的情况下,将对象的功能加以扩展。

装饰模式(Decorator)的角色

  • 抽象构件角色:给出一个抽象接口,以规范准备接收附加责任的对象。
  • 具体构件角色:定义一个将要接收附加责任的类。
  • 装饰角色:持有一个构件对象的引用,并定义一个与抽象构建接口一直的接口
  • 具体装饰角色:负责给构件对象添加附加的责任。

装饰模式(Decorator)的特点

  • 装饰对象和真实对象拥有相同的接口。
  • 装饰对象包含一个真实对象的引用。
  • 装饰对象接收所有来自客户端的请求。
  • 装饰对象可以在转发这些请求以前或者以后添加一些附件的功能。

上述都是一些纯理论的知识,很难去真正的理解和在实际工作中运用,下面我们可以通过例子去展示,然后在回过头来在看上述的理论知识可能会理解深刻一点。

装饰模式(Decorator)的例子

  • 抽象构件角色
/**
 * 抽象构件角色
 */
public interface Componet {
    /**
     * 定义doSomething方法
     */
    void doSomething();

}
  • 具体构件角色
/**
 * 具体构件角色
 */
public class ConcreteComponent implements Componet {
    @Override
    public void doSomething() {
        System.out.println("功能A");

    }
}
  • 装饰角色
/**
 * 装饰角色
 * 1 实现抽象构件角色 Componet
 */
public class Decorator implements Componet {
    /**
     * 2 持有实现抽象构件角色的引用
     */
    private Componet componet;

    public Decorator(Componet componet) {
        this.componet = componet;
    }

    @Override
    public void doSomething() {
        /**
         * 实现有componet引用进行执行
         */
        componet.doSomething();
    }
}

  • 具体装饰角色 1
/**
 * @author: mahan
 * @date: 2019/5/20
 * @Description:
 **/
public class ConreteDecirator1 extends Decorator {
    public ConreteDecirator1(Componet componet) {
        super(componet);
    }

    @Override
    public void doSomething() {
        //执行父类doSomething
        super.doSomething();
        //添加额外的功能
        this.doAnotherThing();
    }

    private void doAnotherThing() {
        System.out.println("功能B");
    }
}
  • 具体装饰角色 2
/**
 * @author: mahan
 * @date: 2019/5/20
 * @Description:
 **/
public class ConreteDecirator2 extends Decorator {

    public ConreteDecirator2(Componet componet) {
        super(componet);
    }

    @Override
    public void doSomething() {
        //执行父类doSomething
        super.doSomething();
        //添加额外的功能
        this.doAnotherThing();
    }

    private void doAnotherThing() {
        System.out.println("功能C");
    }
}
  • 测试
public class Test {
    public static void main(String[] args) {
        Componet componet3 = new ConreteDecirator2(new ConreteDecirator1(new ConcreteComponent()));
        //实现三个功能
        componet3.doSomething();
        System.out.println("-----------------");
        Componet componet2 = new ConreteDecirator1(new ConcreteComponent());
        //实现二个功能
        componet2.doSomething();
        System.out.println("-----------------");
        Componet componet1 = new ConcreteComponent();
        //实现一个功能
        componet1.doSomething();
    }
}
  • 结构
功能A
功能B
功能C
-----------------
功能A
功能B
-----------------
功能A

适用场景

  • 想要透明并且动态的给对象添加新的功能而不影响其他对象
  • 给对象添加的职责在未来可能会发生变化
  • 用子类扩展功能不实际的情况下
发布了59 篇原创文章 · 获赞 30 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_33249725/article/details/90413455