秒懂设计模式之装饰者模式(Decorator Pattern)

news/2024/10/31 3:21:15/

定义

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

使用场景

  • 需要在运行时动态的给一个对象增加额外的职责时候
  • 需要给一个现有的类增加职责,但是又不想通过继承的方式来实现的时候(应该优先使用组合而非继承),或者通过继承的方式不现实的时候(可能由于排列组合产生类爆炸的问题)。

具体实现

第一步:先声明一个原始对象的接口

public interface ICoffee {void makeCoffee();
}

第二步:构建我们的原始对象,此处为原味咖啡对象,它实现了ICoffee接口。

public class OriginalCoffee implements ICoffee {@Overridepublic void makeCoffee() {System.out.print("原味咖啡 ");}
}

第三步:构建装饰者抽象基类,它要实现与原始对象相同的接口ICoffee,其内部持有一个ICoffee类型的引用,用来接收被装饰的对象

public abstract class CoffeeDecorator implements ICoffee {private  ICoffee coffee;public CoffeeDecorator(ICoffee coffee){this.coffee=coffee;}@Overridepublic void makeCoffee() {coffee.makeCoffee();}
}

第四步:构建各种装饰者类,他们都继承至装饰者基类 CoffeeDecorator。此处生成了两个,一个是加奶的装饰者,另一个是加糖的装饰者。

public class MilkDecorator extends CoffeeDecorator {public MilkDecorator(ICoffee coffee) {super(coffee);}@Overridepublic void makeCoffee() {super.makeCoffee();addMilk();}private void addMilk(){System.out.print("加奶 ");}    
}
public class SugarDecorator extends CoffeeDecorator {public SugarDecorator(ICoffee coffee) {super(coffee);}@Overridepublic void makeCoffee() {super.makeCoffee();addSugar();}private void addSugar(){System.out.print("加糖");} 
}

第五步:客户端使用

    public static void main(String[] args) {//原味咖啡ICoffee coffee=new OriginalCoffee();coffee.makeCoffee();System.out.println("");//加奶的咖啡coffee=new MilkDecorator(coffee);coffee.makeCoffee();System.out.println("");//先加奶后加糖的咖啡coffee=new SugarDecorator(coffee);coffee.makeCoffee();}

输出:

原味咖啡 
原味咖啡 加奶 
原味咖啡 加奶 加糖 

可以从客户端调用代码看出,装饰者模式的精髓在于动态的给对象增减功能

当你你需要原味咖啡时那就生成原味咖啡的对象,而当你需要加奶咖啡时,仅仅需要将原味咖啡对象传递到加奶装饰者中去装饰一下就好了。如果你加了奶还想加糖,那就把加了奶的咖啡对象丢到加糖装饰者类中去装饰一下,一个先加奶后加糖的咖啡对象就出来了。

永不磨灭的设计模式 - ShuSheng007


http://www.ppmy.cn/news/307844.html

相关文章

SSD7~

又搬来了一个适合嵌入式的框架哦 对计算和内存的高需求是将现有目标检测网络部署到嵌入式设备中的最大挑战。现有的轻量级目标检测器直接使用轻量级神经网络架构,如MobileNet或在大尺度分类数据集上预先训练,导致网络结构灵活性差,不适用于某…

iOS开发 静态库和动态库

库是程序代码的集合,是程序开发者与其他开发者之间进行代码共享的一种方式。库根据源代码的公开情况可以分为开源库和闭源库。开源库的源代码可见,比如afnetworking;闭源库的源代码不可见,是一段编译好的二进制代码。闭源库又根据…

C#学习笔记(七):ListProduct list = new ListProduct()

// 商品集合信息List<Product> list new List<Product>(){new Product() {Id 1,Name "IPhone4",Price 1999,Remark "心动不如行动"},new Product() {Id 2,Name "IPhone4s",Price 2999,Remark "心动不如行动"},ne…

js中文对象数组转换为普通数组对象

后台返回的是这样的都是中午并且是动态的&#xff0c;都没有属性值 {“颜色”:[“红色}”,“黑色”],“型号”:[“iphone6s”,“iphone7s”],“内存”:[“2G”]} 第一步转换为json对象 let specListData JSON.parse(res.data.data.objs) let temp [] //定义空数组 //获取元素…

想要学习C++,就必须要学习C语言吗?

在学习C之前&#xff0c;你必须先学习C语言吗&#xff1f; C读作C加&#xff0c;简称CPlusPlus。顾名思义&#xff0c;C是在C语言的基础上增加新特性&#xff0c;玩新花样&#xff0c;所以叫CPlusPlus&#xff0c;就像iPhone7S和iPhone7.Win10和Win7的关系一样。 在学习C之前&…

苹果手机还原后无法激活

写在前面&#xff0c;当我们使用的手机是iPhone7s plus 及其以下版本手机时&#xff0c;系统还原会出现【无法激活】的问题。下面就告诉你如何解决这一问题&#xff1a; 找一台联网电脑下载最新版本的iTunes -> 在苹果官网上下载将苹果手机连接Wifi -> 此时&#xff0c;…

Java语法核心——面向对象编程

目录 面向过程思想概述 面向对象思想概述 面向对象思想特点及举例 类与对象的关系 类的定义 类与对象的案例(demo02) 对象内存存储机制 成员变量和局部变量的区别 private关键字 封装 ​编辑 this关键字 ​编辑 构造方法 ​编辑 标准类的代码写法和测试 面向对象…

苹果iPhone7s怎么查询激活时间?

摘要: 之前有一些网友给小编留言问苹果iphones7s怎么查询激活时间&#xff0c;小编一开始并没有把这个问题放心上。不过最近问苹果怎么查询激活时间的人甚至有时候比问 苹果手机找回方法的人还要多&#xff01;因为现在市面上购买到假iPhone7的 ... 之前有一些网友给小编留言问…