Java设计模式——装饰者模式

Java设计模式——装饰者模式

1.简介

'装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许用户通过在一个对象上动态地添加职责或行为来增强其功能。这种类型的设计模式属于对象结构型模式,在不需要改变一个对象的内部结构的条件下,给对象动态地增加一些额外的职责。装饰者模式相比生成子类更为灵活。

2.核心组成

装饰者模式主要包含以下四种角色:

  1. 抽象组件(Component):定义一个对象的接口,可以给这些对象动态地添加职责。
  2. 具体组件(ConcreteComponent):实现或继承抽象组件,并添加基础的行为或属性。
  3. 装饰者(Decorator):持有一个抽象组件的引用,并定义一个与抽象组件一致的接口。
  4. 具体装饰者(ConcreteDecorator):实现装饰者接口,并给具体组件对象添加额外的职责。

3.工作原理

装饰者模式的工作原理是动态地将责任附加到对象上。若要扩展一个类的功能,装饰者提供了一个比继承更有弹性的替代方案。

4.使用场景

  1. 动态地给一个对象添加功能:装饰者模式允许我们在运行时动态地给一个对象添加职责,而不是在编译时静态地定义。
  2. 扩展功能不改变接口:使用装饰者模式时,不需要修改现有类的接口,就可以在运行时动态地扩展类的功能。
  3. 透明地使用对象:装饰者模式中的装饰者对象和被装饰对象实现了相同的接口,所以客户端代码可以透明地使用它们,不需要知道它们到底是装饰者对象还是被装饰对象。

5.优缺点

优点

  1. 装饰者和被装饰对象有相同的超类,因此继承了装饰者模式中的装饰对象和被装饰对象的类型一致性的特点。
  2. 装饰者模式可以动态地扩展一个实现类的功能,且可以无限制地使用装饰模式。
  3. 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。

缺点

  1. 多层装饰比较复杂。
  2. 装饰模式会导致设计中出现许多小类,如果过度使用会使程序变得很复杂。

6.Java的实现例子

我们将以Beverage(饮料)作为抽象组件,并有一个具体的Coffee(咖啡)实现。我们将为咖啡添加一些装饰者,如Milk(牛奶)和Sugar(糖)。

首先,定义Beverage接口和Coffee类:

// 抽象组件:Beverage  
public interface Beverage {  String getDescription();  double cost();  
}  // 具体组件:Coffee  
public class Coffee implements Beverage {  @Override  public String getDescription() {  return "Coffee";  }  @Override  public double cost() {  return 2.0;  }  
}

接下来,定义Decorator类,它实现了Beverage接口并持有一个Beverage对象的引用:

// 装饰者:Decorator  
public abstract class Decorator implements Beverage {  protected Beverage beverage;  public Decorator(Beverage beverage) {  this.beverage = beverage;  }  @Override  public String getDescription() {  return beverage.getDescription();  }  @Override  public double cost() {  return beverage.cost();  }  
}

现在,定义具体的装饰者类,如MilkSugar

// 具体装饰者:Milk  
public class Milk extends Decorator {  public Milk(Beverage beverage) {  super(beverage);  }  @Override  public String getDescription() {  return beverage.getDescription() + ", Milk";  }  @Override  public double cost() {  return beverage.cost() + 0.5;  }  
}  // 具体装饰者:Sugar  
public class Sugar extends Decorator {  public Sugar(Beverage beverage) {  super(beverage);  }  @Override  public String getDescription() {  return beverage.getDescription() + ", Sugar";  }  @Override  public double cost() {  return beverage.cost() + 0.3;  }  
}

最后,在主程序中使用装饰者:

public class BeverageTest {  public static void main(String[] args) {  Beverage beverage = new Coffee();  System.out.println(beverage.getDescription() + " $" + beverage.cost());  Beverage beverageWithMilk = new Milk(beverage);  System.out.println(beverageWithMilk.getDescription() + " $" + beverageWithMilk.cost());  Beverage beverageWithMilkAndSugar = new Sugar(beverageWithMilk);  System.out.println(beverageWithMilkAndSugar.getDescription() + " $" + beverageWithMilkAndSugar.cost());  }  
}

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

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

相关文章

基于国产LoRa的智慧农业解决方案--ASR6601、SX1278

我国《数字乡村发展战略纲要》明确指出“要推进农业数字化转型”,加快推广云计算、大数据、物联网、人工智能在农业生产经营管理中的运用。 然而,目前我国的农业数字化转型还面临着诸多挑战。我国整体农业机械化程度和自动化控制水平仍然较低。由于农田面…

Golang RPC实现-day02

导航 Golang RPC实现一、客户端异步并发多个请求1、 客户端结构体2、 一个客户端,异步发送多个请求,使用call结构体代表客户端的每次请求3、客户端并发多个请求4、客户端接收请求 Golang RPC实现 day01 我们实现了简单的服务端和客户端。我们简单总结一…

蓝桥杯-外卖店优先级(简单写法)

“饱了么”外卖系统中维护着 N 家外卖店,编号 1∼N。 每家外卖店都有一个优先级,初始时 (0 时刻) 优先级都为 0。 每经过 1 个时间单位,如果外卖店没有订单,则优先级会减少 1,最低减到 0;而如果外卖店有订…

【数据结构】双向循环链表专题解析

实现自己既定的目标,必须能耐得住寂寞单干。💓💓💓 目录 •✨说在前面 🍋知识点一:双向链表的结构 • 🌰1."哨兵位"节点 • 🌰2.双向带头循环链表的结构 🍋…

基于java的超级玛丽游戏的设计与实现(论文 + 源码)

Java的超级玛丽游戏.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89313347 基于java的超级玛丽游戏的设计与实现 摘要 近年来,Java作为一种新的编程语言,以其简单性、可移植性和平台无关性等优点,得到了广泛地应用。J2SE称…

(程序设计语言)传值、传引用

1、传值(传递值): 在传值的情况下,函数接收到的是参数的一个副本,而不是参数本身。这意味着函数内部对参数的修改不会影响到原始值。传值通常用于基本数据类型(如整数、浮点数、布尔值等)的传递…

微信小程序原生全局状态管理——wxminishareddata

一个基于原生小程序的 mini 轻量全局状态管理库,跨页面/组件数据共享渲染。 全局状态 data 支持所有 Page 和 Component。类似 Vuex 的使用适合原生小程序,即使后期引入,也只需增加几行代码。目前为第一版,很粗糙,但也…

前端 CSS 经典:CSS 包含块

前言:CSS 总的来说就两块,样式计算和视觉格式化模型,而包含块就是视觉格式化模型的重要内容,理解包含块的定义,对于 CSS 布局有更好的帮助。 1. 概念 什么叫包含块,指的是一个区域,某一个元素在…

华焰天下晋升质量管理三大体系和产品3C认证实力级

华焰天下,作为业界领先的新能源灶具企业,一直以来都致力于追求卓越的质量管理和产品创新。近日,华焰天下成功晋升为质量管理三大体系先进管理,并成功获得了产品3C认证,这标志着我们在质量管理和产品安全方面迈出了坚实…

ThreadLocal,一次到位

一、定义 ThreadLocal是线程私有变量&#xff0c;用于保存每个线程的私有数据。 那么什么情况下需要进行线程隔离 二、源码分析 public class ThreadLocalTest01 {ThreadLocal<Integer> t new ThreadLocal<>();public void test() {t.set(1);Integer integer…

传输层协议——TCP协议

TCP协议又叫传输控制协议&#xff0c;TCP/IP协议是计算机通信网络中目前使用最多的协议&#xff0c;同时也融入了生活的方方面面&#xff0c;不管是浏览网页使用的http/https协议、物联网设备使用的MQTT/MQTTS协议与下载文件使用的ftp协议、工业以太网中使用的Modbus TCP协议等…

JVM学习-虚拟机栈

虚拟机栈 每个线程创建时都会创建一个虚拟机栈&#xff0c;其内部保存一个个栈帧&#xff0c;对应一次次Java方法调用&#xff0c;栈是线程私有的。 生命周期: 与线程相同 作用 主管Java程序的运行&#xff0c;它保存方法的局部变量、部分结果、并参与方法的调用和返回。 …

PyTorch之list、ndarray、tensor数据类型相互转换

温故而知新&#xff0c;可以为师矣&#xff01; 一、参考资料 python中list、numpy、torch.tensor之间的相互转换 二、常用操作 list 转 numpy ndarray np.array(list) import numpy as npa_list [[j for j in range(5)] for i in range(3)] a_ndarray np.array(a_lis…

云服务器配置mysql允许被远程连接从而使用图形化界面

介绍 在云服务器上搭建和配置数据库是进行网站和应用开发的关键步骤之一。本文将介绍如何在云服务器上设置 MySQL 8 和 MySQL 5&#xff0c;以允许远程连接&#xff0c;从而让你的数据库能够被远程用户访问。这样你的本机就可以访问linux服务器上的mysql能&#xff0c;就可以使…

254 基于matlab的钢筋混凝土非线性分析

基于matlab的钢筋混凝土非线性分析&#xff0c;根据梁本构关系&#xff0c;然后进行非线性分析&#xff0c;绘制弯矩-曲率曲线。可设置梁的截面尺寸、混凝土本构&#xff0c;钢筋截面面积等相关参数&#xff0c;程序已调通&#xff0c;可直接运行。 254 钢筋混凝土非线性分析 弯…

利用管道通信(pipe)测量进程间的上下文切换(context switch)开销

利用管道通信(pipe)测量进程间的上下文切换(context switch)开销 《https://pages.cs.wisc.edu/~remzi/OSTEP/cpu-mechanisms.pdf》 Measuring the cost of a context switch is a little trickier. The lmbench benchmark does so by running two processes on a single CPU…

qmake、CMake、make和Makefile

为了跟踪C工程的全部部分&#xff0c;要求有一种机制来精确地指定&#xff1a; 涉及的输入文件&#xff0c;如源代码文件&#xff1a;.cpp&#xff0c;头文件&#xff1a;.h建立程序时所需的工具&#xff0c;如编译器&#xff1a; g.exe&#xff0c;链接器&#xff1a;ld.exe&a…

哈夫曼编码的应用

数据结构与算法课的一个简单实验&#xff0c;记录一下&#xff0c;以供参考。 文章目录 要求测试样例统计字母出现次数建立哈夫曼树对字符编码对原文进行编码译码 要求 输入一段100—200字的英文短文&#xff0c;存入一文件a中。统计短文出现的字母个数n及每个字母的出现次数…

终于搞懂Linux 设备树中的#address-cells,#size-cells 和reg 属性

目录 一、前置知识 1. 处理器平台2. reg 属性的基本格式3. reg 属性的作用 reg 用法 二、#address-cells 和 #size-cells 属性 1. 示例1 2. 示例23. 示例3 一、前置知识 要理解#address-cells和#size-cell 这两个属性&#xff0c;就要先了解 reg属性。 1. 处理器平台 下…

VS2022如何添加现有项

以 想在队列里&#xff0c;使用堆栈的.c&#xff0c;.h文件 为例 目录 1.复制堆栈的.c&#xff0c;.h文件 ​编辑 2.打开队列所在项目的文件夹 3.粘贴堆栈的.c&#xff0c;.h文件 4.在头文件和源文件添加相应的堆栈的.c&#xff0c;.h文件 1.复制堆栈的.c&#xff0c;.h文件…