【愚公系列】软考中级-软件设计师 052-面向对象技术(设计模式-行为型)
🏆 作者简介,愚公搬代码
🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,51CTO博客专家等。
🏆《近期荣誉》:2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏
🚀前言
🔎1.设计模式概念
设计模式是在软件设计领域中,为解决常见问题而被反复使用、被广泛认可的一种设计思想。它是一种经过实践验证的,被认为是最佳解决方案的经验总结,可以帮助开发人员快速高效地解决软件设计中的一些固有问题。
每一个设计模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动。设计模式的核心在于提供了相关问题的解决方案,使得人们可以更加简单方便的复用成功的设计和体系结构。
设计模式具有以下特点:
特点 | 描述 |
---|---|
在特定情况下被使用 | 设计模式并不是适用于所有场景的通用解决方案,而是在特定问题领域中被广泛使用的解决方案。 |
涉及多种设计元素 | 设计模式涉及到多个设计元素,包括类,对象,接口,继承,组合等等。 |
以面向对象方式进行设计 | 设计模式主要是针对面向对象编程而提出的,尽管也可以用于其他编程范式。 |
遵循设计原则 | 设计模式往往遵循一些设计原则,如单一职责原则、开闭原则、里氏替换原则等,以提高设计的可维护性、可扩展性和可重用性。 |
🔎2.设计模式分类
设计模式的四个基本要素:模式名称、问题(应该在何时使用模式)、解决方案(设计的内容)、效果(模式应用的效果)。
分为三类,创建型模式主要是处理创建对象,结构型模式主要是处理类和对象的组合,行为型模式主要是描述类或者对象的交互行为,具体如下(红色粗体记忆关键字表示常考必须记住的):
类型 | 描述 |
---|---|
架构模式 | - 软件设计中的高层决策,如C/S结构 - 反映了开发软件系统过程中所作的基本设计决策 |
设计模式 | - 描述了一个在我们周围不断重复发生的问题和其解决方案的核心 - 提供了相关问题的解决方案,使得人们可以更加简单方便地复用成功的设计和体系结构 - 包含四个基本要素:模式名称、问题(应该在何时使用模式)、解决方案(设计的内容)、效果(模式应用的效果) |
惯用法 | - 最低层的模式,关注软件系统的设计与实现 - 通过特定的编程语言描述构件与构件之间的关系 - 每种编程语言都有自己的惯用法,即语言的特定模式(如C++中的引用计数) |
🚀一、设计模式-行为型
行为型设计模式:关注对象之间的通信、职责分配和算法的交互方式。它们帮助我们更好地管理对象之间的关系,使系统更具灵活性和可维护性
🔎1.责任链模式(Chain of Responsibility Pattern)
责任链模式就如同传递请求一样,多个对象按顺序尝试处理请求,直到有一个对象能够处理为止。
生活中的例子:在一个公司中,员工请假申请可能需要经过多个级别的审批,例如部门主管、部门经理和总经理。每个级别的主管都有权决定是否批准员工的请假申请。当员工提交请假申请后,首先会由部门主管进行审批,如果部门主管批准了请假申请,那么流程结束;如果部门主管拒绝了请假申请,那么请假申请会被传递给部门经理进行审批,同样如果部门经理批准了请假申请,流程结束;如果部门经理也拒绝了请假申请,那么请假申请会被传递给总经理进行审批。总经理是最后一个级别的审批者,他的决定是最终决定。这个过程中,如果任何一个级别的主管批准了请假申请,那么就会结束审批流程,否则,请求会一直被传递下去,直到有一个对象能够处理请求为止。
🔎2.命令模式(Command Pattern)
命令模式就像使用遥控器来控制设备。你将命令封装在遥控器按钮中,然后可以随时执行命令。生活中的一个例子是电视遥控器。
通过电视遥控器,你可以执行各种命令,例如打开电视、切换频道或调整音量。当你按下遥控器上的按钮时,电视就会接收到对应的命令,并执行相应的操作。这样,你不需要亲自操作电视机上的按钮或控制面板,只需使用遥控器就可以方便地控制电视。
举个例子,当你想要打开电视时,你可以按下遥控器上的电源按钮。这个按钮上封装了“打开电视”的命令,当你按下按钮时,遥控器会发送这个命令给电视机,电视机就会打开。同样地,如果你想要切换频道,你可以按下对应的频道按钮,这个按钮上封装了相应的“切换频道”的命令,电视就会切换到你想要的频道。
通过命令模式,我们可以将具体的命令与执行命令的对象(比如电视)解耦合,从而实现更灵活的控制。我们可以将各种命令封装在遥控器的按钮中,并在需要时执行这些命令,而无需关心具体是如何执行的。
除了电视遥控器,命令模式还可以应用于其他场景,比如智能家居系统中的遥控器、电梯控制面板等。无论是哪种情况,命令模式都提供了一种方便的方式来控制设备,并将操作命令与具体操作解耦合,提高了系统的可扩展性和灵活性。
🔎3.解释器模式(Interpreter Pattern)
解释器模式用于处理语言解释和编译器等领域。它定义了一种语言的语法表示,并提供了解释器来解释这种语法。在编程中,正则表达式是解释器模式的一个实例,用于匹配和解释字符串模式。
举例来说,假设我们要编写一个程序来验证一个邮箱地址是否合法。我们可以使用正则表达式作为解释器来解释邮箱地址的语法规则。我们可以定义邮箱地址的语法规则,例如:一个合法的邮箱地址应该包含一个@符号和一个域名,而域名又由一个或多个单词组成,每个单词之间用点号(.)分隔。通过编写一个解释器来解释这个语法规则,我们可以对任意的邮箱地址进行验证,判断其是否合法。
例如,我们使用正则表达式解释器来解释邮箱地址的规则:
- 规则1:一个合法的邮箱地址应该包含一个@符号
- 规则2:@符号之前可以有一个或多个字符
- 规则3:@符号之后应该是一个或多个单词,每个单词之间用点号(.)分隔
通过使用解释器模式和正则表达式,我们可以创建一个邮箱地址验证器,输入一个邮箱地址,程序会根据定义的规则进行解释和验证,返回是否合法的结果。
🔎4.迭代器模式(Iterator Pattern)
迭代器模式是一种类似于遍历集合的设计模式。它提供了一种按顺序访问集合元素的方法,而无需直接暴露集合的内部结构。
举个生活中的例子来说明,假设你想要看电视节目表上的所有节目。你可以选择按照时间顺序一个一个地查看节目,这就是使用迭代器模式的一种示例。你无需知道节目表的内部结构,只需按照顺序逐一访问节目即可。
在编程中,迭代器模式同样适用。假设你有一个存储各种数据的集合,例如数组、列表或集合。使用迭代器模式,你可以通过创建一个迭代器对象来遍历集合中的元素,而无需了解底层数据结构。迭代器会按照一定的顺序返回集合中的每个元素,你可以根据需要对每个元素执行特定的操作。这样,你就可以方便地处理集合中的数据,而不用关心具体的数据结构。
🔎5.中介者模式(Mediator Pattern)
中介者模式就像是一个中间人,在多个对象之间协调交互。通过使用中介者模式,可以减少对象之间的直接通信,从而降低耦合度。
一个生活中的例子是在一个团队中,项目经理可以充当中介者的角色。项目经理负责协调团队成员之间的合作和沟通,以确保项目的顺利进行。项目经理作为中介者,可以处理团队成员之间的冲突和协调不同的需求和意见。通过项目经理的介入,团队成员可以专注于自己的任务,而不必直接与其他成员沟通和协调。这样,中介者模式帮助提高了团队的效率和协作能力。
🔎6.备忘录模式(Memento Pattern)
备忘录模式是一种保存和还原状态的设计模式。它允许你保存对象的状态,以便将来可以还原到先前的状态。
生活中的例子可以是在文本编辑器中使用撤销和重做功能。当我们在编辑文本时,可以通过撤销操作回到之前的状态,然后再次使用重做操作恢复到之前的修改。这就是备忘录模式的应用。
🔎7.观察者模式(Observer Pattern)
观察者模式类似于订阅通知。多个观察者(订阅者)订阅主题(发布者),当主题有新信息时,观察者会自动接收通知。
这种模式在生活中有许多例子,比如社交媒体平台。当你关注某个用户或主题时,系统会将他们的更新信息发送给你。举个例子,假设你在Twitter上关注了某个名人,每当这个名人发布新推文时,你会在你的主页上看到他的推文。在这里,你就是观察者,名人是主题,Twitter系统负责将新推文通知给你。
🔎8.状态模式(State Pattern)
状态模式类似于人的不同情绪状态。就像一个人可以处于高兴、生气或伤心等不同的状态一样,每种状态下的行为可能不同。
举个生活中的例子:在自动售货机中,售货机可能有不同的状态,如待机、售卖中、缺货等。每种状态下,售货机的行为都不同。例如,在待机状态下,售货机可能会显示一个欢迎界面,并等待用户选择商品;在售卖中状态下,售货机会接受用户的投币或刷卡,并出货商品;而在缺货状态下,售货机可能会显示一个提示信息,告诉用户该商品暂时缺货。
通过状态模式,售货机可以根据当前的状态灵活地执行不同的行为,使操作更加简便和智能。
🔎9.策略模式(Strategy Pattern)
策略模式类似于根据不同情况选择不同解决方案来解决同一个问题。通过选择不同的策略,我们可以实现相同的目标。
生活中的例子是在旅行规划中。在旅行规划中,我们希望到达一个目的地。然而,我们可以选择使用不同的交通工具作为我们的策略来达到目的地。例如,我们可以选择开车、乘坐火车或乘坐飞机。这些交通工具都是解决相同问题的不同策略。根据不同的情况,我们可以选择适合我们需要的策略来实现我们的目标。
举个例子,假设我们想去一个离我们家很远的城市旅行。如果我们有自己的汽车,那么我们可以选择开车去这个城市。这个策略可以使我们自由地掌控旅行的时间和路线。另一方面,如果我们没有汽车,但是有高速铁路可以直接到达目的地,那么我们可以选择乘坐火车作为我们的策略。如果我们非常着急,希望快速到达目的地,可能会选择乘坐飞机,这样可以更快地到达。无论我们选择哪种交通工具作为策略,我们的目标都是到达目的地,只是选择了不同的策略来实现相同的目标。
这个例子展示了策略模式的思想,通过选择不同的策略来解决相同的问题,我们可以根据不同的情况选择最适合的策略来实现我们的目标。
🔎10.模板方法模式(Template Method Pattern)
模板方法模式就像是定义了一个算法的框架,但允许子类实现其中的一些步骤。在生活中的例子中,烹饪可以是一个使用模板方法模式的场景。假设我们有一个烹饪系统,其中有一个抽象的Cook类,它定义了一个烹饪方法cooking()。这个烹饪方法包含了一些固定的步骤,如准备、烹饪和装盘。
具体的烹饪步骤和材料可能因每道菜而异。因此,我们可以创建具体的子类,如SteakCook和PastaCook,来实现这些具体的步骤。子类可以重写cooking()方法中的一些步骤,以符合它们具体的烹饪需求。
举个例子,假设我们有一个SteakCook子类。在它的cooking()方法中,它可以重写准备步骤,使用牛排所需的材料和方法。然后,它可以继续使用Cook类的烹饪和装盘步骤,因为这些步骤在制作任何菜肴时都是相同的。
另一方面,如果我们有一个PastaCook子类,它可以重写烹饪步骤,使用面条和调味料。然后,它可以继续使用Cook类的准备和装盘步骤。
通过使用模板方法模式,我们可以在一个抽象类中定义共享的算法框架,但允许子类根据自己的需要实现和定制其中的一些步骤。这样,我们可以避免重复的代码,并提供灵活性和可扩展性。
🔎11.访问者模式(Visitor Pattern)
访问者模式类似于访问不同类型的元素。你可以定义不同的访问者来执行不同类型元素的操作。
举一个生活中的例子来说明:在一个图书馆里,可能有各种不同类型的书籍,比如小说、科普书和艺术书。不同类型的书籍可能需要不同类型的读者来浏览和理解。
在这个例子中,访问者可以是不同类型的读者,例如一个文学爱好者可以是访问者,他对小说感兴趣并懂得如何欣赏文学作品。另外,一个科学爱好者也可以是访问者,他对科普书感兴趣并能够理解科学知识。还有一个艺术爱好者,他可以是访问者,他喜欢欣赏艺术书中的绘画和设计。
通过定义不同类型的访问者,我们可以针对不同类型的书籍执行不同的操作。比如,文学爱好者可以读取小说中的故事情节和对话,并欣赏其中的文学技巧。科学爱好者可以阅读科普书中的科学原理和实验,并从中获取科学知识。艺术爱好者可以欣赏艺术书中的绘画作品,并了解艺术家的创作思想和技巧。
通过访问者模式,我们可以让不同类型的访问者来访问不同类型的书籍,从而实现对元素的不同操作。这样,每个访问者可以专注于自己擅长的领域,并且可以灵活地添加新的访问者和元素,以适应不断变化的需求。
🚀二、二十三种设计模式习题集
🚀感谢:给读者的一封信
亲爱的读者,
我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。
如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。
我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。
如果您愿意支持我的创作,请扫描下面二维码,您的支持将不胜感激。同时,如果您有任何反馈或建议,也欢迎与我分享。
再次感谢您的阅读和支持!
最诚挚的问候, “愚公搬代码”
- 点赞
- 收藏
- 关注作者
评论(0)