津津乐道设计模式 - 装饰者模式详解(以女友化妆场景带你彻底明白)

本文主要是介绍津津乐道设计模式 - 装饰者模式详解(以女友化妆场景带你彻底明白),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》本专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

津津乐道设计模式 - 装饰者模式详解

  • 什么是装饰者模式
  • 装饰者模式适用场景
  • 生活及代码案例
  • 装饰者模式优缺点
  • 结语

什么是装饰者模式

装饰者模式(Decorator Pattern)是一种结构设计模式,它允许你在不改变现有对象结构的情况下,动态地将新行为添加到对象中。

装饰者模式通过创建一个包装器类,该类包装了原始对象,并在保持接口不变的情况下,提供了额外的功能。这个包装器类被称为装饰者,它可以在被装饰对象执行之前或之后,执行一些额外的操作。

装饰者模式适用场景

在生活中装饰者模式的应用也比较多,比如给房子装修、给汽车改装等,都是在为对象扩展一些额外的功能,装饰者模式适用以下场景:

  • 动态地添加功能:装饰者模式适用于需要在运行时动态地为对象添加额外功能的场景。它允许你根据需要组合不同的装饰者,以实现各种不同的功能组合。
  • 避免使用子类的继承:装饰者模式提供了一种替代使用子类继承的方式来扩展对象功能的方法。通过装饰者模式,你可以通过组合装饰者来扩展对象的功能,而无需创建大量的子类。
  • 单一职责原则:装饰者模式允许你将对象的功能划分为多个单一职责的类,每个类都专注于特定的功能,符合单一职责原则。

装饰者模式适用于需要动态地添加功能、避免使用大量子类继承和遵循单一职责原则的场景。它可以提供一种灵活的方式来扩展对象的功能,同时保持代码的可维护性和可扩展性。

生活及代码案例

之前我们在讲解 模版模式详解 的时候,我们那女朋友化妆的流程来演示,同样本次装饰者模式也同样可以以女朋友化妆的场景来讲解。

假设你的女朋友正在准备参加一场重要的约会 😳,她希望能够化一个美丽而独特的妆容。现在我们使用装饰者模式来设计化妆的过程。

首先,我们有一个基本的化妆类,表示女朋友的原始妆容:

//定义接口
public interface Makeup {void apply();
}
//定义女朋友的原始妆容
public class BasicMakeup implements Makeup {@Overridepublic void apply() {System.out.println("女朋友的原始妆容");}
}

然后,我们定义一个装饰者抽象类,表示不同的化妆步骤的装饰者:

//定义一个装饰者抽象类
public abstract class MakeupDecorator implements Makeup {protected Makeup makeup;public MakeupDecorator(Makeup makeup) {this.makeup = makeup;}@Overridepublic void apply() {makeup.apply();}
}

接下来,我们可以定义具体的化妆步骤装饰者类,如打底、眼妆和唇妆:

public class PrimerDecorator extends MakeupDecorator {public PrimerDecorator(Makeup makeup) {super(makeup);}@Overridepublic void apply() {super.apply();System.out.println("打底妆");}
}public class EyeMakeupDecorator extends MakeupDecorator {public EyeMakeupDecorator(Makeup makeup) {super(makeup);}@Overridepublic void apply() {super.apply();System.out.println("眼妆");}
}public class LipMakeupDecorator extends MakeupDecorator {public LipMakeupDecorator(Makeup makeup) {super(makeup);}@Overridepublic void apply() {super.apply();System.out.println("唇妆");}
}

现在,我们可以使用装饰者模式来组合不同的化妆步骤来完成女朋友的妆容,例如:

public class DecoratorPatternTest {public static void main(String[] args) {//女朋友初始妆容Makeup makeup = new BasicMakeup();//底妆装饰makeup = new PrimerDecorator(makeup);//眼妆装饰makeup = new EyeMakeupDecorator(makeup);//唇妆装饰makeup = new LipMakeupDecorator(makeup);makeup.apply();}
}

输出结果如下:
在这里插入图片描述
这样通过装饰者模式,我们可以动态地为女朋友的妆容添加不同的化妆步骤,实现个性化和多样化的妆容效果。

装饰者模式优缺点

装饰者模式的优点

  • 灵活性:装饰者模式允许你在不改变现有对象结构的情况下,动态地添加或修改对象的功能。你可以根据需要组合不同的装饰者,以实现各种功能组合,从而提供灵活的扩展性。

  • 单一职责原则:装饰者模式将功能划分到不同的类中,每个类都专注于特定的功能,符合单一职责原则。这使得每个类的代码更加清晰、简洁,并且易于理解和维护。

  • 开闭原则:装饰者模式支持开闭原则,即对扩展开放,对修改关闭。你可以通过添加新的装饰者类来扩展对象的功能,而无需修改现有的代码。这使得系统更加稳定,易于扩展和维护。

  • 组合多个装饰者:装饰者模式可以同时应用多个装饰者,通过组合不同的装饰者,你可以实现更复杂的功能组合,满足不同的需求。

装饰者模式的缺点

  • 复杂性增加:引入装饰者类和装饰者之间的关联关系,会增加系统的复杂性。需要理解每个装饰者的作用和调用顺序,以确保装饰者的正确组合和执行顺序。

  • 可能产生大量的类:如果需要大量的装饰者来实现各种功能组合,可能会导致类的数量增加,使得代码结构复杂化。因此,需要权衡装饰者的使用,避免过度装饰。

  • 动态装饰的限制:装饰者模式通常是通过组合来实现功能的动态添加,但在某些情况下,如果需要在运行时动态地移除装饰者或更改装饰者的顺序,会比较困难。

总的来说,装饰者模式在提供灵活性和扩展性方面有很大优势,但在设计时需要权衡复杂性和类的数量,确保合理使用装饰者模式,并根据具体需求进行权衡。

结语

本章节主要讲解的是装饰者模式应用场景、装饰者模式优缺点,并以女朋友化妆场景,使用装饰者模式动态地为女朋友的妆容添加不同的化妆步骤的形式,书写JAVA代码进行演示,加深大家的印象。如果本文对你有用,欢迎关注收藏评论,大家一起探讨~

样例代码:https://github.com/lhmyy521125/toher-designmode

这篇关于津津乐道设计模式 - 装饰者模式详解(以女友化妆场景带你彻底明白)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/324355

相关文章

Mysql数据库聚簇索引与非聚簇索引举例详解

《Mysql数据库聚簇索引与非聚簇索引举例详解》在MySQL中聚簇索引和非聚簇索引是两种常见的索引结构,它们的主要区别在于数据的存储方式和索引的组织方式,:本文主要介绍Mysql数据库聚簇索引与非... 目录前言一、核心概念与本质区别二、聚簇索引(Clustered Index)1. 实现原理(以 Inno

使用python生成固定格式序号的方法详解

《使用python生成固定格式序号的方法详解》这篇文章主要为大家详细介绍了如何使用python生成固定格式序号,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下... 目录生成结果验证完整生成代码扩展说明1. 保存到文本文件2. 转换为jsON格式3. 处理特殊序号格式(如带圈数字)4

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

MyBatis常用XML语法详解

《MyBatis常用XML语法详解》文章介绍了MyBatis常用XML语法,包括结果映射、查询语句、插入语句、更新语句、删除语句、动态SQL标签以及ehcache.xml文件的使用,感兴趣的朋友跟随小... 目录1、定义结果映射2、查询语句3、插入语句4、更新语句5、删除语句6、动态 SQL 标签7、ehc

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1