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

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

装饰者模式

基本定义

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

模式结构

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. 需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。
相关推荐
RainbowSea8 小时前
12. LangChain4j + 向量数据库操作详细说明
java·langchain·ai编程
RainbowSea8 小时前
11. LangChain4j + Tools(Function Calling)的使用详细说明
java·langchain·ai编程
考虑考虑12 小时前
Jpa使用union all
java·spring boot·后端
用户37215742613512 小时前
Java 实现 Excel 与 TXT 文本高效互转
java
浮游本尊13 小时前
Java学习第22天 - 云原生与容器化
java
渣哥15 小时前
原来 Java 里线程安全集合有这么多种
java
间彧15 小时前
Spring Boot集成Spring Security完整指南
java
间彧16 小时前
Spring Secutiy基本原理及工作流程
java
数据智能老司机16 小时前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
Java水解17 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试