设计模式--装饰器模式【结构型模式】

设计模式的分类

我们都知道有 23 种设计模式,这 23 种设计模式可分为如下三类:

  • 创建型模式(5 种):单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。
  • 结构型模式(7 种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  • 行为型模式(11 种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

设计模式系列文章传送门

设计模式的 7 大原则

设计模式--单例模式【创建型模式】

设计模式--工厂方法模式【创建型模式】

设计模式--抽象工厂模式【创建型模式】

设计模式--建造者模式【创建型模式】

设计模式--原型模式【创建型模式】

设计模式--适配器模式【结构型模式】

什么是装饰器模式

装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许在运行时动态地向对象添加新的功能,而不改变其结构和实现,它在运行时给对象动态地添加一些额外的职责,装饰者模式通过装饰来实现功能的扩展,装饰器的核⼼就是在不改原有类的基础上给类新增功能。

装饰着模式的组成

  • 抽象构件(Component):被装饰者对象需要实现的一个抽象接口或抽象类。
  • 具体构件(ConcreteComponent):一个具体的对象,就是需要被装饰的对象。
  • 抽象装饰器(Decorator):持有一个抽象构件对象的引用,并且可以动态给该对象添加新的功能。
  • 具体装饰器(ConcreteDecorator):实现具体的装饰器,向真实的构件对象添加新功能。

装饰器模式实现

我们再次使用车来做为演示的实物载体,生活中我们买了爱车之后,除了 4S 店交付的新车,我们把车开回家之后,还会对车进行一番装饰0例如地垫、儿童座椅、360 安全影像等等,而这些都属于对爱车的装饰,也就是具体的装饰器,而我们的爱车就是抽象组件。

MyCar(抽象构件)

我们以车为抽象构件,代码如下:

java 复制代码
public interface MyCar {

    //装饰车
    String decorativeCar();

}

MyCarDecorator(具体构件)

我们有了爱车之后需要对爱车进行内饰装饰,内饰装饰就是具体的构件,代码如下:

java 复制代码
public interface MyCar {

    //装饰车
    String decorativeCar();

}

InteriorDecorator(抽象装饰器)

我们对爱车内饰装饰定义一个抽象装饰器,代码如下:

java 复制代码
public abstract class InteriorDecorator implements MyCar {

    private MyCar myCar;

    public InteriorDecorator(MyCar myCar) {
        this.myCar = myCar;
    }

    @Override
    public String decorativeCar() {
        return "爱车装饰";
    }
}

FloorMatDecorator(具体装饰器)

我们定义一个具体的地垫装饰器,代码如下:

java 复制代码
public class FloorMatDecorator extends InteriorDecorator {
    public FloorMatDecorator(MyCar myCar) {
        super(myCar);
    }

    @Override
    public String decorativeCar() {
        return "爱车装饰地垫";
    }
}

ChildSeatDecorator(具体装饰器)

我们定义一个具体的儿童座椅装饰器,代码如下:

java 复制代码
public class ChildSeatDecorator extends InteriorDecorator {

    public ChildSeatDecorator(MyCar myCar) {
        super(myCar);
    }

    @Override
    public String decorativeCar() {
        return "爱车装饰儿童座椅";
    }
}

客户端验证

我们进行装饰器模式案例验证,代码如下:

java 复制代码
public class ClientDecorator {

    public static void main(String[] args) {
        //具体组件
        MyCarDecorator myCarDecorator = new MyCarDecorator();
        //具体装饰器 地垫装饰
        FloorMatDecorator floorMatDecorator=new FloorMatDecorator(myCarDecorator);
        String floor = floorMatDecorator.decorativeCar();
        System.out.println(floor);
        //具体装饰器 儿童座椅
        ChildSeatDecorator childSeatDecorator=new ChildSeatDecorator(myCarDecorator);
        String childSeat = childSeatDecorator.decorativeCar();
        System.out.println(childSeat);

    }

}

验证结果如下:

powershell 复制代码
爱车装饰地垫
爱车装饰儿童座椅

以上我们就完成了装饰器模式的演示,装饰器解决了直接继承下因功能的不断横向扩展导致⼦类数量膨胀的问题,使用装饰器模式后就会⽐直接继承显得更加灵活,同时也无需再考虑⼦类的维护。

装饰器模式的优缺点

优点:

  • 符合单一职责原则,每个具体装饰器类只负责增加一种功能,类的职责单一。
  • 灵活可扩展,可以动态地为对象添加新的功能。
  • 使用装饰器对象,可以避免因继承导致的⼦类数量膨胀的问题。

优点:

  • 会产生较多的对象,让系统变的更复杂,同时设计模式的使用考验研发人员的抽象能力和系统设计能力。

装饰器模式使用场景

  • Java 中数据流处理中的输入输出流是装饰者模式的经典应用。
  • 结合场景分析,没有万能的设计模式。。。

如有不正确的地方欢迎各位指出纠正。

相关推荐
进击的野人2 小时前
Vue 组件与原型链:VueComponent 与 Vue 的关系解析
前端·vue.js·面试
程序员小假2 小时前
我们来说一下消息的可靠性投递
java·后端
席之郎小果冻2 小时前
【04】【创建型】【聊一聊,建造者模式】
java·前端·建造者模式
LYFlied2 小时前
TypeScript 常见面试问题
ubuntu·面试·typescript
原来是好奇心2 小时前
深入Spring Boot源码(四):Starter机制与依赖管理深度解析
java·源码·springboot·starter
阿杆2 小时前
如何在 Spring Boot 中接入 Amazon ElastiCache
java·数据库·redis
努力学算法的蒟蒻2 小时前
day35(12.16)——leetcode面试经典150
算法·leetcode·面试
cheems95272 小时前
锁策略的介绍
java·开发语言
武子康2 小时前
Java-199 JMS Queue/Topic 集群下如何避免重复消费:ActiveMQ 虚拟主题与交付语义梳理
java·分布式·消息队列·rabbitmq·activemq·mq·java-activemq
LSL666_3 小时前
12 MyBatis的连接池
java·服务器·mybatis