设计模式之装饰器设计模式/包装设计模式

news/2025/2/22 19:13:58
  • 装饰器设计模式(Decorator Pattern)

    • 也叫包装设计模式,属于结构型模式,它是作为现有的类的一个包装,允许向一个现有的对象添加新的功能,同时又不改变其结构

    • 给对象增加功能,一般两种方式,继承或关联组合,将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌入对象的行为来增强功能,这个就是装饰器模式,比继承模式更加灵活

    • 以动态、透明的方式给单个对象添加职责,但又能不改变其结构

    • JDK源码里面应用最多的就是IO流,大量使用装饰器设计模式

      在这里插入图片描述

  • 角色(装饰者和被装饰者有相同的超类Component)

    • 抽象组件(Component)
      • 定义装饰方法的规范,最初的自行车,仅仅定义了自行车的API
      • InputStream
    • 被装饰者(Concrete Component)
      • Component的具体实现,也就是我们要装饰的具体对象
      • 实现了核心角色的具体自行车
      • FileInputStream、ByteArrayInputStream
    • 装饰者组件(Decorator)
      • 定义具体装饰者的行为规范,和Component角色有相同的接口,持有组件(Component)对象的实例应用
      • 自行车组件都有名称和价格
      • FilterInputStream
    • 具体装饰物(Concrete Decorator)
      • 负责给构件对象装饰附加的功能
      • 比如喇叭、防爆胎等
      • BufferedInputStream、DataInputSteam
  • 代码实战示例

    /**
     * 通用组件
     */
    interface Bike {
        String getDescription();
    
        int getPrice();
    }
    
    /**
     * 具体的被装饰者(Concrete Component)
     */
    class BigBike implements Bike {
        private String description = "大号自行车";
    
        @Override
        public String getDescription() {
            return this.description;
        }
    
        @Override
        public int getPrice() {
            return 200;
        }
    }
    
    /**
     * 装饰者组件
     */
    class BikeDecorator implements Bike {
        private String description = "我只是装饰器,啥都不表示,子类帮我传递";
    
        @Override
        public String getDescription() {
            return this.description;
        }
    
        @Override
        public int getPrice() {
            return 0;
        }
    }
    
    /**
     * 具体装饰物:防爆胎
     */
    class BSCBikeDecorator extends BikeDecorator {
    
        private String description = "增加50元的防爆胎";
    
        private Bike bike;
    
        public BSCBikeDecorator(Bike bike) {
            this.bike = bike;
        }
    
        @Override
        public String getDescription() {
            return bike.getDescription() + "," + this.description;
        }
    
        @Override
        public int getPrice() {
            return bike.getPrice() + 50;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Bike bigBike = new BigBike();
            bigBike = new BSCBikeDecorator(bigBike);
            bigBike = new BSCBikeDecorator(bigBike);
    
            System.out.println(bigBike.getDescription());
            System.out.println(bigBike.getPrice());
        }
    }
    
  • 优点

    • 装饰模式与继承关系的目的都是要扩展对象的功能,但装饰模式可以提供比继承更多的灵活性
    • 使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合,原有代码无须改变,符合“开闭原则”
  • 缺点

    • 装饰模式增加了许多子类,如果过度使用会使程序变得很复杂(多层包装)
    • 增加了系统的复杂度,加大学习与理解的难度
  • 装饰器模式与桥接模式对比

    • 相同点都是通过封装其他对象达到设计的目的,和对象适配器也类似,有时也叫半装饰设计模式
    • 没有装饰者和被装饰者的主次区分,桥接和被桥接者是平等的,桥接可以互换,不用继承自同一个父类
    • 桥接模式不用使用同一个接口;装饰模式用同一个接口装饰,接口在父类中定义

http://www.niftyadmin.cn/n/5862671.html

相关文章

软考—系统架构设计(案例 | 论文)

系统设计(案例|论文) 系统设计是系统分析的延伸与拓展。系统分析阶段解决“做什么”的问题,而系统设计阶段解决“怎么做”的问题。 概要设计 系统设计的主要内容包括概要设计和详细设计。概要设计又称为系统总体结构设计&#…

如何成为一名合格的单片机工程师----引言介绍篇(1)

前言 在当今数字化时代,单片机(Microcontroller Unit,MCU)已成为电子设备的核心组件之一,广泛应用于智能家居、工业自动化、汽车电子、物联网等领域。作为一名单片机工程师,你将有机会参与到各种创新项目中…

代码随想录算法训练day62---图论系列6《并查集2》

代码随想录算法训练 —day62 文章目录 代码随想录算法训练前言一、108.冗余连接二、109. 冗余连接II总结 前言 今天是算法营的第62天,希望自己能够坚持下来! 今天继续并查集系列!今日任务: ● 108.冗余连接 ● 109.冗余连接II 一…

【SPIE出版,见刊快速,EI检索稳定,浙江水利水电学院主办】2025年物理学与量子计算国际学术会议(ICPQC 2025)

2025年物理学与量子计算国际学术会议(ICPQC 2025)将于2025年4月18-20日在中国杭州举行。本次会议旨在汇聚全球的研究人员、学者和业界专家,共同探讨物理学与量子计算领域的最新进展与前沿挑战。随着量子技术的快速发展,其在信息处…

安装 redis 5.0.14 版本

下载 gcc rpm 包 在能上网的服务器下执行如下命令下载安装包 $> yum install --downloadonly --downloaddir/DATA/soft/temp gcc 或使用如下命令下载 # 安装yum-utils $ yum -y install yum-utils # 下载 gcc 依赖包 $ yumdownloader --resolve --destdir/rpm gcc # 参数…

项目汇报PPT转视频制作 | 有字幕和配音版

步骤 下载剪映; 按照稿子和PPT的节奏先进行配音的录制(每句话都按照想要的时间间隔来控制好位置; 点击选中文本就会出现下面的画面 点击朗读可以选择配音的声音; 导出制作好的录音,添加到PPT中作为背景音&#xff…

open webui 部署 以及解决,首屏加载缓慢,nginx反向代理访问404,WebSocket后端服务器链接失败等问题

项目地址:GitHub - open-webui/open-webui: User-friendly AI Interface (Supports Ollama, OpenAI API, ...) 选择了docker部署 如果 Ollama 在您的计算机上,请使用以下命令 docker run -d -p 3000:8080 --add-hosthost.docker.internal:host-gatewa…

OkHttp使用和源码分析学习(二)

流程及源码分析 OkHttpClient使用过程主要涉及到OkHttpClient、Request、Response、Call、Interceptor,具体参考OkHttp使用。OkHttp在设计时采用门面模式,将整个系统复杂性隐藏,子系统通过OkHttpClient客户端对外提供。 流程 创建 OkHttp…