Java设计模式中装饰者模式/装饰者模式具体内容是什么/静态代理与装饰者模式联系与区别是什么

news2024/11/19 14:38:06

继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用!

5.4 装饰者模式

5.4.1 概述

在不改变现有对象结构的情况下,动态给对象增加某些职责或功能的模式

5.4.2 结构

  • 抽象构件(Component):定义一个抽象接口以规范准备接受附加功能的对象
  • 具体构件(Concrete Component):实现抽象构件,通过装饰角色为其添加功能后职责
  • 抽象装饰(Decorator):继承或实现抽象构件,包含具体构件的实例,可通过其子类扩展具体构件中功能
  • 具体装饰(Concrete Decorator):实现抽象装饰方法,给具体构件对象添加附加功能或职责

5.4.3 案例(快餐店)

  • 快餐类–抽象构建类
public abstract class FastFood {  
    private float price;  
    private String description;  
    public float getPrice() {  
        return price;  
    }  
    public void setPrice(float price) {  
        this.price = price;  
    }  
    public String getDescription() {  
        return description;  
    }  
    public void setDescription(String description) {  
        this.description = description;  
    }  
    public FastFood(float price, String description) {  
        this.price = price;  
        this.description = description;  
    }  
    public FastFood() {  
    }  
    public abstract float cost();  
}
  • 具体构建角色-炒饭
public class FiredRice extends FastFood{  
    public FiredRice() {  
        super(10,"炒饭");  
    }  
    @Override  
    public float cost() {  
        return getPrice();  
    }  
}
  • 具体构建角色-炒面
public class FiredNoodles extends FastFood{  
    public FiredNoodles()  
    {  
        super(12,"炒面");  
    }  
    @Override  
    public float cost() {  
        return getPrice();  
    }  
}
  • 鸡蛋类-具体装饰者
 **/  
public class Egg extends Garnish{  
    @Override  
    public float cost() {  
//        计算价格 鸡蛋+快餐  
        return getPrice() + getFastFood().cost();  
    }  
    public Egg(FastFood fastFood) {  
        super(1, "鸡蛋", fastFood);  
    }  
    @Override  
    public String getDescription() {  
        return super.getDescription() + getFastFood().getDescription();  
    }  
}
  • 培根类-具体装饰者
public class Bacon extends Garnish{  
    @Override  
    public float cost() {  
//        计算价格 培根+快餐  
        return getPrice() + getFastFood().cost();  
    }  
    public Bacon(FastFood fastFood) {  
        super(2, "培根", fastFood);  
    }  
    @Override  
    public String getDescription() {  
        return super.getDescription() + getFastFood().getDescription();  
    }  
}
  • 测试
    public static void main(String[] args) {  
//        点一份炒饭  
        FastFood firedRice = new FiredRice();  
        System.out.println(firedRice.getDescription() +  firedRice.cost() + "元");  
//        上面炒饭加蛋  
        firedRice = new Egg(firedRice);  
        System.out.println(firedRice.getDescription() +  firedRice.cost() + "元");  
//        上面炒饭加蛋  
        firedRice = new Egg(firedRice);  
        System.out.println(firedRice.getDescription() +  firedRice.cost() + "元");  
        //        上面炒饭加培根  
        firedRice = new Bacon(firedRice);  
        System.out.println(firedRice.getDescription() +  firedRice.cost() + "元");  
    }
  • 结果![[Pasted image 20230103224228.png]]
  • 类图![[Pasted image 20230103224305.png]]

5.4.4 优点

  • 可以带来比继承更灵活的扩展功能,使用更加方便
  • 可组合不同装饰着对象获取不同行为状态的多样化结果
  • 装饰类和被装饰类可以独立发展,不会相互耦合
  • 可以动态扩展一个实现类的功能

5.4.5 使用场景

  • 当不能采用继承方法对系统进行扩充或采用继承不利于系统扩展和维护时:
  • 不能采用继承情况主要有2类:
    • 系统中存在大量按独立扩展,为支持每一种组合将产生大量子类,使得子类数目呈指数爆炸性增长
    • 类定义不能被继承,如final类
  • 在不影响其它对象情况下,以动态、透明方式给单个对象添加职责
  • 当对象功能要求可以动态添加时或再动态撤销时

5.4.6 JDK源码

  • IO流中的包装类使用了装饰者模式,BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter等类。
  • 以BufferedWriter为例,说明简单使用BuffererWriter
public class Demo{
public static void main(String args[]) throw Exception{
		//创建BufferedWriter对象
		//创建FileWriter对象
		FileWriter filWriter = new FileWriter("./a.txt");
		BufferedWriter bufferedWriter = new BufferedWriter(filWriter);
		//写数据
		bufferedWriter.write("hello world");
		bufferedWriter.close();
	}
}
  • 结构![[Pasted image 20230104155701.png]]
    BufferedWriter使用装饰者模式对Writer子类进行增强,添加缓冲区,提高数据读写效率。

5.4.7 静态代理与装饰区别

5.4.7.1 相同点

  • 均要实现与目标类相同业务接口
  • 在两个类中均要声明目标对象
  • 均可以在不修改目标类前提下增加目标方法

5.4.7.2 不同点

  • 目的不同
    • 装饰者:增强目标对象
    • 静态代理:保护和隐藏目标对象
  • 获取目标对象构建地方不同
    • 装饰者:由外界传来,可通过构造方法传递
    • 静态代理:在代理类内部创建,以此来隐藏目标对象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/148988.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Javascript 中的堆、栈、引用和值

学透CSS-强烈推荐 Javascript 中的内存存储 栈-Stack: 这是当前 Javascript 线程的暂存空间。由于 Javascript 通常只有单线程,因此通常只有一个堆栈。堆栈的大小也是有限的。 堆-Heap ,它是应用程序级别的动态内存存储。从堆中访问和检索…

java 手把手带你创建一个spring入门案例

查看本文 首先 您需要下载spring 如果没有安装 可以查看我的文章 java spring下载步骤 首先 我们打开idea开发工具 选择左上角 File > New > Project 如下图操作 勾选 然后点击下一步 然后我们选择项目目录 这里我直接用了个中文目录 最好不要跟我学哦 因为个人英文不…

微信语音转换成mp3文件保存的简单详细步骤

目录 读者手册 一、前言 二、操作步骤一 把语音转化为silk文件(silk后缀的文件) 1.长按语音收藏(手机操作) 2.找到主页收藏 3.找到收藏的语音 4.转存为笔记 5.点击笔记里面的语音(下面全部电脑操作&#xff0…

Kubernetes(k8s) 笔记总结(一)

文章目录1. 云平台2. 私有网络 VPC(重点!!!)3. Kubernetes 介绍4. k8s 架构5. kubectl 和 kubeadm6. 三台云服务器的 安装部署7. Kubernetes 环境搭建7.1 安装docker环境7.2 安装k8s的 预备环境8. kubernetes集群 安装的三大件(kubelet、kube…

三句话,让Ai帮你画18万张图

本文介绍Stable Diffusion的快速上手,本地部署,以及更多有趣的玩法展示。 在 DALL-E 2 和 Imagen 之后,AI绘图领域又一个热乎的深度学习模型出炉——Stable Diffusion 。8月份发布的 Stable Diffusion 更加高效且轻量,可以在消费…

P4:Transforms的使用

transform.py就像是一个工具箱,里面有很多工具(如:totensor、resize等不同的工具)。 使用规则: 拿特定格式的图片,通过使用工具,得到想要的结果。 1、transforms.ToTensor()的使用 1、作用&a…

实战1:基于tensorflow卷积网络实现面部关键点检测详细教程(代码+数据)

项目概述: 此任务的目标是预测面部图像上的关键点位置。这可以用作多个应用程序中的构建块,例如:检测面部关键点是一个非常具有挑战性的问题。人脸特征因人而异,即使是单个人,由于 3D 姿势、大小、位置、视角和光照条件等因素也存在很大差异。 直接上结果: 数据集描…

JSP SSM 个人博客系统系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 JSP SSM 个人博客系统系统是一套完善的web设计系统(系统采用SSM框架进行设计开发,springspringMVCmybatis),对理解JSP java编程开发语言有帮助,系统具有完整的源代 码和数据库,系统主要采…

vue3-Teleport笔记

简单来写一下Teleport src/components/TeleportLearn.vue <script setup></script><template><div><Teleport to"body"><div>你好</div></Teleport></div> </template><style scoped></style&…

NVMe IO数据传输如何选择PRP or SGL?

在Host与Controller之间有数据交互时&#xff0c;Controller会多次访问Host内存。比如执行NVMe Read/Write:当Host下发NVMe Write命令时&#xff0c;Host会先放数据放在Host内存中&#xff0c;然后通知Controller过来取数据。Controller接到信息后&#xff0c;会通过PCIe Memor…

Python下载ts文件视频并合并

目录 一、ts文件的由来 二、下载ts文件 1.下载index.m3u8&#xff0c;并做相应处理 2.下载ts文件 三、合并ts文件 一、ts文件的由来 ts文件&#xff0c;ts即"Transport Stream"的缩写&#xff0c;特点就是要求从视频流的任一片段开始都是可以独立解码的&#x…

C 程序设计教程(06)—— C 语言的运算符与表达式

C 程序设计教程&#xff08;06&#xff09;—— C 语言的运算符与表达式 该专栏主要介绍 C 语言的基本语法&#xff0c;作为《程序设计语言》课程的课件与参考资料&#xff0c;用于《程序设计语言》课程的教学&#xff0c;供入门级用户阅读。 目录C 程序设计教程&#xff08;0…

【每日一题】【LeetCode】【第七天】盛最多水的容器

解决之路 因为是周日&#xff0c;找个中等题挑战一下。 题目描述 测试案例&#xff08;部分&#xff09; 第一次 想一下&#xff0c;因为涉及到底乘高&#xff0c;所以不能排序。逆序也没必要。 简化一下题干&#xff0c;盛水最多&#xff0c;也就是算面积最大&#xff0c…

【北邮果园大三上】运筹学期中前

第一章.线性规划 1.1例题 根据现实世界中的问题建立模型 一般表达式 ①和式 ②向量式 1.2变化标准&#xff1a; 1.3线性规划求解的基础原理和单纯解法 1.3.1解 ①基础概念 基 可行解与基础解 其他分类 ②判断举例 原式子&#xff1a; 判断标准 将一个未知数作为常熟&#…

从Wireshark看TCP连接的建立与关闭

http://t.zoukankan.com/jonathanlin-p-4282582.html TCP是一种面向连接、可靠的协议。TCP连接的建立与断开&#xff0c;都是需要经过通信双方的协商。用一句话概括就是&#xff1a;三次握手say hello&#xff08;建立连接&#xff09;&#xff1b;四次握手say goodbye&#x…

蓝桥杯Python组排序算法与函数

目录 一、排序算法 二、排序函数 1、Python 的 sort() 函数和 sorted() 函数 2、sort() 例子 3、sorted() 例子 4、部分排序 三、例题 1、统计数字&#xff08;lanqiaoOJ题号535&#xff09; 2、错误票据&#xff08;lanqiaoOJ题号205&#xff09; 3、奖学金&#xf…

线程池 - ThreadPoolExecutor 详解

线程池 - ThreadPoolExecutor 详解 线程池 ThreadPoolExecutor 源码解析参考 juc 专栏系列文章。 基本概述 线程池&#xff1a;一个容纳多个线程的容器&#xff0c;容器中的线程可以重复使用&#xff0c;省去了频繁创建和销毁线程对象的操作。 线程池作用&#xff1a; 降低资…

【基础】Elasticsearch 基础

Elasticsearch 基本概念及使用Elasticsearch 基本概念ES 的简介及使用场景ES 基本概念ES 与 Kibana 的安装Elasticsearch 分词器ES 内置分词器ik 分词器的安装和使用Elasticsearch 基本使用索引操作数据的增删改查DSL 查询聚合查询批量操作Elasticsearch 基本概念 ES 的简介及…

多线程锁相关

日升时奋斗&#xff0c;日落时自省 目录 1、常见的锁策略 1.1、悲观锁vs乐观锁 1.2、轻量级锁vs重量级锁 1.3、自旋锁vs挂起等待锁 1.4、互斥锁vs读写锁 1.5、公平锁vs非公平锁 1.6可重入锁vs不可重入锁 2、CAS 2.1、CAS解析 2.2、CAS的应用场景 2.2.1、实现原子类 …

JavaSE学习day2_03, 算数运算符

5. 算术运算符 5.1 分类&#xff1a; - * / % 5.2 细节&#xff1a; 1.运算规则。跟小学数学是一模一样的 2.如果是整数跟整数进行计算&#xff0c;结果只能是整数。直接去掉小数部分&#xff0c;保留整数。如5/22,而不是2.5. 3.如果想要结果中有小数&#xff0c;需要有小…