设计模式——装饰器模式

594 阅读3分钟

「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

概述Decorator

目的

向一个存在的对象中增加新的功能,且不改其结构。相对于子类更加灵活且没有那么臃肿

描述

就像是名称一样“装饰”,装饰即给物品增加了新的功能“展览”,又保留物品原本的功能属性。而这个装饰的存在与否不影响这个物品的本质功能

使用场景

  1. 动态增加功能,动态撤销
  2. 类功能类似于子类的扩展

例子

「杯子」杯子本来可以用来装水,但是杯子挂了一个挂件

「肉夹馍」肉夹馍摊子上

  • 只有一个馍
  • 带有肉的馍
    • 带有牛肉的馍
    • 带有猪肉的馍
  • 带有包装袋的馍
    • 带有纸袋的馍
    • 带有塑料袋的馍
  • 带有塑料袋和牛肉的馍
  • 。。。。。。

实现

逻辑实现

  1. 杯子这个接口,有一个方法,takeInWater();装水
  2. 有大杯子和小杯子,大杯子可以装1000ml,小杯子可以装500ml
  3. 有一个带有装饰物的杯子的抽象类,其中有一个属性是杯子,还有一个方法是挂件pendant()
  4. 带有装饰物的杯子的实现类,pendant()方法是挂了一个小猪

代码实现

  1. 创建基类的接口Cup,并定义一个方法“装水”
/**
 * @ClassName Cup
 * @Desc 杯子的接口
 * @Author YangMingYu
 * @Date 2021/10/29 3:54 下午
 * @Version 1.0
 **/
public interface Cup {
    /**
     * 装水
     */
    public void takeInWater();
}

  1. 创建两个接口的实现largeCupsmallCup
/**
 * @ClassName LargeCup
 * @Desc 大杯子可以装1000ml
 * @Author YangMingYu
 * @Date 2021/10/29 3:54 下午
 * @Version 1.0
 **/
public class LargeCup implements Cup{
    @Override
    public void takeInWater() {
        System.out.println("i can take 1000ml water!!!");
    }
}

/**
 * @ClassName SmallCup
 * @Desc 小杯子可以装500ml
 * @Author YangMingYu
 * @Date 2021/10/29 3:55 下午
 * @Version 1.0
 **/
public class SmallCup implements Cup {
    @Override
    public void takeInWater() {
        System.out.println("i can only take 500ml water!!!");
    }
}
  1. 创建Cup的装饰器DecoratorCup,带有挂件的杯子
/**
 * @ClassName CupDecorator
 * @Desc 带有装饰物的杯子
 * @Author YangMingYu
 * @Date 2021/10/29 3:56 下午
 * @Version 1.0
 **/
public abstract class DecoratorCup implements Cup {

    protected Cup decoratorCup;

    public DecoratorCup(Cup cup) {
        this.decoratorCup = cup;
    }

    /**
     * 实现装水的操作
     */
    public void takeInWater() {
        decoratorCup.takeInWater();
        takeDecorator();
    }

    /**
     * 带挂件,具体挂件是什么实现类决定
     */
    public abstract void takeDecorator();

}
  1. 实现装饰器,小熊挂件的杯子
/**
 * @ClassName LittleBearDecoratorCup
 * @Desc 带有小熊装饰物的杯子
 * @Author YangMingYu
 * @Date 2021/10/29 3:59 下午
 * @Version 1.0
 **/
public class LittleBearDecoratorCup extends DecoratorCup {

    public LittleBearDecoratorCup(Cup cup) {
        super(cup);
    }

    public void takeDecorator() {
        System.out.println("i take a little bear");
    }
}

总结

使用装饰器模式:创建的对象可以是没有装饰器的也可以是带有各种各样的装饰器的。

也就是这个只是一个装饰,改变不了本质是这个馍可以吃

然后这个装饰可有可无,并不影响吃这个操作

只是自己确实很不理解,为什么要将这个模式归于结构型模式,在开发中也使用过(肯定没有这么标准的使用,装饰器并没有创建抽象类再去实现)但是还是归咎于是在创建自己需要的对象。这样看来又像是创建型模式

最后补充一句,也是看到好多博客都在说的一个问题,确实如此,这种装饰器模式其实有些违背了开发的原则,也就是很多功能在开发后期进行一个补充操作。而且装饰器和原本的接口其实是完全区分出来了的,也就是后期进行维护的时候,可能根本就想不起来这边还有一个装饰器。所以活用活现吧,具体问题具体分析