这篇系列文章将按照以下结构逐一介绍不同种类的设计模式:
1. 创建型模式
2. 结构型模式
3. 行为型模式
- 行为型模式涉及类和对象之间的协作,以完成单个对象无法独立完成的任务,并分配职责。这部分将介绍十一种行为型模式:模板方法模式、策略模式、命令模式、责任链模式、状态模式、观察者模式、中介者模式、迭代器模式、访问者模式、备忘录模式和解释器模式。
通过这一系列文章,深入了解这些不同类型的设计模式,以及它们如何在软件开发中发挥关键作用。
在软件开发中,设计模式是一种被广泛接受的可复用解决方案,用于解决在软件设计中常见的问题。设计模式为开发人员提供了一种通用的指导,帮助他们设计和实施高质量、易维护、可扩展的软件系统。
本文将快速入门行为型模设计模式中的中介者模式。
中介者模式是一种行为型设计模式,它通过引入一个中介者对象来协调多个对象之间的交互。中介者模式的核心思想是将对象之间的通信行为集中到一个中介者对象中,而不是让对象直接相互引用。这样可以降低对象之间的耦合度,使得对象之间的交互更加灵活和可扩展。
中介者模式的主要优点有:
- 降低了对象之间的耦合度:通过引入中介者对象,对象之间不再直接相互引用,而是通过中介者进行通信,从而降低了对象之间的耦合度。
- 简化了对象之间的交互:中介者模式将对象之间的通信行为集中到一个中介者对象中,使得对象之间的交互更加简单和直观。
- 可以更灵活地扩展和修改系统:由于对象之间的通信行为都集中在中介者对象中,所以可以通过修改中介者对象来扩展或修改系统的功能,而不需要修改对象之间的交互逻辑。
中介者模式的主要不足有:
- 中介者对象会变得复杂:随着系统的扩展,中介者对象可能会变得非常复杂,因为它需要处理多个对象之间的交互逻辑。
- 可能会导致性能问题:由于中介者对象需要处理多个对象之间的通信,可能会导致性能问题,特别是在对象数量较多或通信频繁的情况下。
中介者模式包含以下几个角色:
抽象中介者(Mediator):定义了对象之间通信的接口,通常包含一个或多个抽象方法。
具体中介者(Concrete Mediator):实现了抽象中介者的接口,负责协调对象之间的通信。
抽象同事类(Colleague):定义了对象的通信接口,通常包含一个中介者对象的引用。
具体同事类(Concrete Colleague):实现了抽象同事类的接口,负责与其他同事类进行通信。
中介者模式适用于以下场景:
- 系统中的对象之间存在复杂的交互关系,导致对象之间的耦合度较高。
- 系统中的对象之间的通信行为需要经常变化或扩展。
- 希望通过一个中介者对象来集中管理对象之间的通信,以便于维护和修改系统。
中介者模式适用于以下场景:
聊天室系统:在一个聊天室系统中,用户之间可以通过中介者对象进行消息的发送和接收。中介者负责将消息传递给其他用户,从而实现用户之间的通信。
航空控制系统:在一个航空控制系统中,飞机、塔台、雷达等对象之间需要进行频繁的通信。通过引入一个中介者对象,可以将飞机的位置信息传递给塔台和雷达,从而实现飞机的控制和监测。
MVC框架:在一个MVC(Model-View-Controller)框架中,模型、视图和控制器之间需要进行交互。通过引入一个中介者对象,可以将模型的数据传递给视图进行显示,同时将用户的操作传递给控制器进行处理。
股票交易系统:在一个股票交易系统中,交易员、股票、交易所等对象之间需要进行交互。通过引入一个中介者对象,可以将交易员的买卖请求传递给交易所进行处理,并将交易结果返回给交易员。
游戏中的多人对战:在一个多人对战的游戏中,玩家之间需要进行实时的通信和协作。通过引入一个中介者对象,可以将玩家的操作传递给其他玩家,从而实现玩家之间的交互和协作。
在奶茶店的场景中,我们可以使用中介者模式来管理顾客、服务员和奶茶制作过程。
首先,我们需要创建一个抽象中介者接口,定义了所有参与者需要实现的方法:
public interface Mediator {
void setMediator(MediatorCenter mediatorCenter);
void sendMessage(String message);
}
接下来,我们创建具体的参与者类,如顾客、服务员和奶茶制作过程:
public class Customer implements Mediator {
private MediatorCenter mediatorCenter;
@Override
public void setMediator(MediatorCenter mediatorCenter) {
this.mediatorCenter = mediatorCenter;
}
@Override
public void sendMessage(String message) {
System.out.println("顾客发送消息: " + message);
mediatorCenter.sendMessageToWaiter(message);
}
}
public class Waiter implements Mediator {
private MediatorCenter mediatorCenter;
@Override
public void setMediator(MediatorCenter mediatorCenter) {
this.mediatorCenter = mediatorCenter;
}
@Override
public void sendMessage(String message) {
System.out.println("服务员发送消息: " + message);
mediatorCenter.sendMessageToCustomer(message);
mediatorCenter.sendMessageToMilkTeaMaker(message);
}
}
public class MilkTeaMaker implements Mediator {
private MediatorCenter mediatorCenter;
@Override
public void setMediator(MediatorCenter mediatorCenter) {
this.mediatorCenter = mediatorCenter;
}
@Override
public void sendMessage(String message) {
System.out.println("制茶员发送消息: " + message);
mediatorCenter.sendMessageToWaiter(message);
mediatorCenter.sendMessageToCustomer(message);
}
}
然后,我们创建一个中介者类,用于协调各个参与者之间的交互:
public class MediatorCenter {
private Customer customer;
private Waiter waiter;
private MilkTeaMaker milkTeaMaker;
public void setCustomer(Customer customer) {
this.customer = customer;
customer.setMediator(this);
}
public void setWaiter(Waiter waiter) {
this.waiter = waiter;
waiter.setMediator(this);
}
public void setMilkTeaMaker(MilkTeaMaker milkTeaMaker) {
this.milkTeaMaker = milkTeaMaker;
milkTeaMaker.setMediator(this);
}
public void sendMessageToCustomer(String message) {
System.out.println("中介者向顾客发送消息: " + message);
// 处理顾客的消息,例如安排服务员等
}
public void sendMessageToWaiter(String message) {
System.out.println("中介者向服务员发送消息: " + message);
// 处理服务员的消息,例如通知顾客等
}
public void sendMessageToMilkTeaMaker(String message) {
System.out.println("中介者向制茶员发送消息: " + message);
// 处理奶茶制作过程的消息,例如通知顾客等
}
}
最后,我们在主函数中创建各个参与者对象,并设置中介者,然后模拟顾客、服务员和奶茶制作过程之间的交互:
public class Client {
public static void main(String[] args) {
MediatorCenter mediatorCenter = new MediatorCenter();
Customer customer = new Customer();
Waiter waiter = new Waiter();
MilkTeaMaker milkTeaMaker = new MilkTeaMaker();
mediatorCenter.setCustomer(customer);
mediatorCenter.setWaiter(waiter);
mediatorCenter.setMilkTeaMaker(milkTeaMaker);
customer.sendMessage("我要点一杯珍珠奶茶");
waiter.sendMessage("马上为您准备一杯珍珠奶茶");
milkTeaMaker.sendMessage("奶茶制作完成,请取用");
}
}
运行结果:
顾客发送消息: 我要点一杯珍珠奶茶
中介者向服务员发送消息: 我要点一杯珍珠奶茶
服务员发送消息: 马上为您准备一杯珍珠奶茶
中介者向顾客发送消息: 马上为您准备一杯珍珠奶茶
中介者向制茶员发送消息: 马上为您准备一杯珍珠奶茶
制茶员发送消息: 奶茶制作完成,请取用
中介者向服务员发送消息: 奶茶制作完成,请取用
中介者向顾客发送消息: 奶茶制作完成,请取用
可以看到中介者模式成功地协调了顾客、服务员和奶茶制作过程之间的交互。
中介者模式是一种非常有用的设计模式,它可以帮助我们降低对象之间的耦合度,简化对象之间的交互,同时也可以更灵活地扩展和修改系统,提高系统的可维护性和可扩展性。
文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib
文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang
文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些
文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器
文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距
文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器
文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn
文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios
文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql
文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...
文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120
文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数