设计模式(结构型设计模式——装饰者模式)

设计模式(结构型设计模式------装饰者模式)

装饰者模式

基本定义

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

模式结构

Component: 抽象构件。是定义一个对象接口,可以给这些对象动态地添加职责。

ConcreteComponent:具体构件。是定义了一个具体的对象,也可以给这个对象添加一些职责。

Decorator:抽象装饰类。是装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator存在的。

ConcreteDecorator:具体装饰类,起到给Component添加职责的功能。

代码实现

Component:抽象构件, 被装饰抽象类
java 复制代码
public interface Cake {
    String nameDetail();
    Double price();
}
ConcreteComponent: 抽象实现类,被装饰对象类
java 复制代码
public class CakeImpl implements Cake {
    /**
     * 手抓饼配料->鸡蛋,牛肉,蔬菜,
     * 组合方式:1.鸡蛋,2.牛肉,3.蔬菜,4. 鸡蛋+牛肉,5. 鸡蛋+蔬菜,6.牛肉+蔬菜, 7.鸡蛋+牛肉+蔬菜
     */
    public String nameDetail() {
        return "原味手抓饼";
    }
    public Double price() {
        return 5d;
    }
}
Decorator: 抽象装饰类
java 复制代码
public class CakeDecorator implements Cake{
    Cake cake;
    //装饰实现类
    public CakeDecorator(Cake cake) {
        this.cake = cake;
    }
    public String nameDetail() {
        return cake.nameDetail();
    }
    public Double price() {
        return cake.price();
    }
}
ConcreteDecorator: Decorator具体实现类

鸡蛋手抓饼 +1.5元

java 复制代码
public class EggCakeDecorator extends CakeDecorator{
    public EggCakeDecorator(Cake cake) {
        super(cake);
    }
    //关键部分
    @Override
    public String nameDetail() {
        return "鸡蛋," + cake.nameDetail();
    }
    @Override
    public Double price() {
        return 1.5 + cake.price();
    }
}

牛肉手抓饼 +2元

java 复制代码
public class MeetCakeDecorator extends CakeDecorator{

    public MeetCakeDecorator(Cake cake) {
        super(cake);
    }

    //关键部分
    @Override
    public String nameDetail() {
        return "牛肉," + cake.nameDetail();
    }
    @Override
    public Double price() {
        return 2 + cake.price();
    }
}

蔬菜手抓饼 +0.5元

java 复制代码
public class VeggCakeDecorator extends CakeDecorator{

    public VeggCakeDecorator(Cake cake) {
        super(cake);
    }

    //关键部分

    @Override
    public String nameDetail() {
        return "蔬菜," + cake.nameDetail();
    }

    @Override
    public Double price() {
        return 0.5 + cake.price();
    }
}
测试类
java 复制代码
@Slf4j
public class Test {

    public static void main(String[] args) {
        Cake cake = new CakeImpl();
        log.info("小红想吃{}, 价格:¥{}", cake.nameDetail(), cake.price());

        CakeDecorator cakeEgg = new EggCakeDecorator(cake);
        log.info("小明想吃{}, 价格:¥{}", cakeEgg.nameDetail(), cakeEgg.price());

        CakeDecorator meetCake = new MeetCakeDecorator(cakeEgg);
        CakeDecorator veggCake = new VeggCakeDecorator(meetCake);
        log.info("小张想吃{}, 价格:¥{}", veggCake.nameDetail(), veggCake.price());
    }
}

优点

  1. 装饰者模式可以提供比继承更多的灵活性。

  2. 可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。

  3. 通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。

  4. 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合"开闭原则"。

缺点

  1. 会产生很多的小对象,增加了系统的复杂性

  2. 这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。

使用场景

  1. 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  2. 需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。
相关推荐
都叫我大帅哥2 小时前
Spring @Transactional 注解完全指南
java·spring
Java成神之路-2 小时前
G1 垃圾回收器 :SATB + TAMS核心机制深度解析
java·jvm
前端工作日常2 小时前
我学习到的JIT即时编译与机器码缓存失效
java·后端
带刺的坐椅2 小时前
Solon 的 10 种 HTTP 服务器:改一行依赖,换一个引擎
java·solon·jetty·undertow·mcp-server·htttp
luj_17682 小时前
星火科技助力边远地区防病攻坚
c语言·开发语言·c++·经验分享·算法
always_TT3 小时前
【Python 日志记录:logging 模块入门】
开发语言·python·php
xcLeigh3 小时前
Go入门:变量声明的五种方式详解
java·开发语言·golang
AI大模型-小华3 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
zmzb01033 小时前
C++课后习题训练记录Day175
开发语言·c++
Mark_ZP4 小时前
【锁1】Synchronized vs ReentrantLock区别
java