介绍

装饰者模式又称为包装模式,平时开发中,我们想要扩展一个现有对象,一般的做法是继承这个对象,然后在子类中添加功能,而装饰者模式就是继承的一种替代方案,也是一种动态扩展对象功能的方法。

定义

动态的给一个对象添加一些额外的职责。

使用场景

需要动态且透明地扩展类的功能时,

类图

结构型设计模式之装饰者模式

角色介绍:

  • Component: 抽象组件,可以是接口或抽象类,其实是被装饰的原始对象。
  • ConcreteComponent:抽象组件具体的实现类,也就是我们装饰的具体对象。
  • Decorator:抽象装饰者,其职责是为了装饰我们的组件对象,其内部一定要含有一个指向组件对象的引用。在大多数情况下该类为抽象类,需要根据不同的装饰逻辑实现不同的具体子类,但是,如果装饰的功能单一,只有一个的情况下我们可以直接使用该类作为具体的装饰者。
  • ConcreteDecoratorA、B:装饰者的具体实现(如果装饰的功能单一,可以省略)。

简单示例

我们平常买一台新手机时,到手的就是一台裸机,没有贴膜,没有保护套,这些装饰都是我们后来加上去的,我们以此为例,把手机定义成一个抽象类:

/**
 * 手机抽象类,即抽象组件角色,要被装饰的对象
 */
public abstract class Phone {

    public abstract void operate();//Phone类下有一个关于手机的抽象操作

}

Phone类就是上面提到的抽象组件类,也就是要被我们装饰的原始对象,然后我们来定义一个具体的被装饰类,例如小米手机:

/**
 * 小米手机,即抽象组件的具体实现类
 */
public class MIPhone extends Phone {

    @Override
    public void operate() {
        System.out.println("一台崭新的小米手机");
    }

}

MIPhone类继承于Phone类,对operate方法作了具体的实现,MIPhone就是我们要装饰的具体对象,现在需要一个装饰者来装饰MIPhone,这里定义一个PhoneDecorator:

/**
 * 表示装饰手机,即装饰者角色
 */
public class PhoneDecorator extends Phone{

    private Phone mPhone;//保持一个对被装饰者的引用

    public PhoneDecorator(Phone phone){
        this.mPhone = phone;
    }

    @Override
    public void operate() {
        operateA();
        mPhone.operate();//调用Phone类中的operate方法
        operateB();
    }

    private void operateA(){
        System.out.println("装上手机套");
    }

    private void operateB(){
        System.out.println("贴膜");
    }
}

在PhoneDecorator中我们保持了一个对Phone类的引用,可以方便的调用具体被装饰对象中的具体方法,然后PhoneDecorator中添加了两个新方法,分别表示对Phone的装饰,然后重写继承自Phone的operate方法,实现装饰逻辑。可以看到这里我并没有定义想类图那样抽象的装饰者,而是直接只定义了一个具体的装饰者类,这是因为我们要添加的装饰并不是很复杂,就没有对装饰者做抽象的提取,如果你要为Phone类添加不同牌子的配件,就可以考虑像类图那样的结构,把装饰者做抽象的提取,然后定义多个具体的装饰着实现。所以开发中要灵活运用,结合实际,不要为了用设计模式而用设计模式。

接下来再看具体的调用:

/**
 * 客户端
 */
public class Client {

    public static void main(String[] args){
        //我买了一台手机
        Phone phone = new MIPhone();
        //我给手机买一些配件
        PhoneDecorator phoneDecorator = new PhoneDecorator(phone);
        phoneDecorator.operate();
    }

}

输出:
装上手机套
一台崭新的小米手机
贴膜

结语

装饰者模式是一个很简单的设计模式,但是它在日常开发中使用的也比较多,而且他和前面讲过的代理模式很相似,不要混淆,这里说一下它们之间的区别:

装饰者模式是一种透明的扩展对象功能的方法,是继承关系的一种代替方案,而代理模式则是给一个对象提供一个代理对象,并且通过代理对象控制原有对象的引用。装饰者模式侧重为装饰对象增强功能,代理模式侧重对代理对象施加控制,但没有功能增强。

本文源码位置

相关文章:

  • 2022-02-10
  • 2021-07-08
  • 2022-01-02
  • 2022-02-10
  • 2021-05-21
  • 2021-10-18
  • 2021-09-06
  • 2021-07-28
猜你喜欢
  • 2022-12-23
  • 2022-02-10
  • 2023-02-25
  • 2022-12-23
  • 2021-12-24
相关资源
相似解决方案