设计模式之中介模式(三分钟学会一个设计模式)

news/2024/11/15 20:05:48/文章来源:https://www.cnblogs.com/jilodream/p/18429808

中介模式(Mediator)又称之为调停模式。
mediator [ˈmiːdieɪtə(r)]
n. 调停者;斡旋者;解决纷争的人(或机构); 本意就是解决纠纷的中间人
它是面向对象六大原则中最少知道原则的一个典型应用。
(关于面向对象六大原则,可看前文:https://www.cnblogs.com/jilodream/p/5353512.html)
大概意思就是类设计时与外界尽量减低耦合,尽量少的依赖其他类,这样就会降低类后期修改的风险。
官方的的定义如下:用一个中介对象来封装一系列的对象交互。中介对象使得其他各个对象不再需要显示的相互引用。使整体的耦合更加松散,而且可以改变独立的改变他们之间的交互。

它是面向对象的23种设计模式中的一种,属于行为模式的范围。
中介模式大概就是这样,比如你去买房,不论是价格讨论,还是房子质量,都通过中介来进行,尽管中介会包装一些逻辑,但是买家不需要管理所有卖家的信息,保留卖家的联系方式。卖家呢也不需要管理买家的信息,保留买家的联系方式。尽管是买卖房子,但是买家和卖家之间都是通过中介来进行交互,并不直接沟通。这样做的好处就是买卖双方都减轻了自己的工作负担,不需要牢记对方的相关特性,所有这些都交给中介来维护。
比如没有加入中介对象时,我们A/B 双方大概需要维护m*n依赖条,如果双方还要互相依赖,则是2*m*n条依赖,当A、B双方的实例越来越多时,情况也会越来越复杂。
当我们加入中介对象时,则只需要维护A/B和中介对象之间的依赖,约2(m+n)条依赖,(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )

区别大概是下面这个样子

直接耦合

通过中介者组织

有些人会说AB 对象我就互相调用一下,需要搞这么复杂么?

如果只是简单调用,当然没必要引入中介类,当然是怎么简单怎么来,但是倘若业务未来(或者已经)依赖很复杂,就应该尽早引入中介类,降低类之间不必要的耦合。

来看一个例子,调用双方是
银行和企业,他们可以互相给对方发消息。我们通过中介模式来组织整体结构:

银行接口:

 1 package com.example.demo.learn.pattern.behavior.mediator;
 2 
 3 /**
 4  * @discription
 5  */
 6 public interface Bank {
 7     void sendMsg(String msg);
 8 
 9     void receiveMsg(String msg);
10 
11     void register(UnionPay unionPay);
12 }

工商银行实现

 1 package com.example.demo.learn.pattern.behavior.mediator;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public class ICBCBank implements Bank {
10 
11     private UnionPay unionPay;
12 
13     @Override
14     public void sendMsg(String msg) {
15         log.warn("工商银行发送消息到企业:" + msg);
16         unionPay.sendCompany(msg);
17     }
18 
19     @Override
20     public void receiveMsg(String msg) {
21         log.warn("工商银行收到企业消息:" + msg);
22     }
23 
24     @Override
25     public void register(UnionPay unionPay) {
26         this.unionPay = unionPay;
27     }
28 }

建设银行实现

 1 package com.example.demo.learn.pattern.behavior.mediator;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public class CCBBank implements Bank {
10 
11     private UnionPay unionPay;
12 
13     @Override
14     public void sendMsg(String msg) {
15         log.warn("建设银行发送消息到企业:" + msg);
16         unionPay.sendCompany(msg);
17     }
18 
19     @Override
20     public void receiveMsg(String msg) {
21         log.warn("建设银行收到企业消息:" + msg);
22     }
23 
24     @Override
25     public void register(UnionPay unionPay) {
26         this.unionPay = unionPay;
27     }
28 }

企业接口

1 package com.example.demo.learn.pattern.behavior.mediator;
2 
3 public interface Company {
4     void sendMsg(String msg);
5 
6     void receiveMsg(String msg);
7 
8     void register(UnionPay unionPay);
9 }

千度公司

 1 package com.example.demo.learn.pattern.behavior.mediator;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public class QianDuCompany implements Company {
10     private UnionPay unionPay;
11 
12     @Override
13     public void sendMsg(String msg) {
14         log.warn("千度公司发送消息到银行:" + msg);
15         unionPay.sendBank(msg);
16     }
17 
18     @Override
19     public void receiveMsg(String msg) {
20         log.warn("千度公司收到银行消息:" + msg);
21     }
22 
23     @Override
24     public void register(UnionPay unionPay) {
25         this.unionPay = unionPay;
26     }
27 }

大米公司

 1 package com.example.demo.learn.pattern.behavior.mediator;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public class DaMiCompany implements Company {
10     private UnionPay unionPay;
11 
12     @Override
13     public void sendMsg(String msg) {
14         log.warn("大米公司发送消息到银行:" + msg);
15         unionPay.sendBank(msg);
16     }
17 
18     @Override
19     public void receiveMsg(String msg) {
20         log.warn("大米公司收到银行消息:" + msg);
21     }
22 
23     @Override
24     public void register(UnionPay unionPay) {
25         this.unionPay = unionPay;
26     }
27 }

中介类

 1 package com.example.demo.learn.pattern.behavior.mediator;
 2 
 3 import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
 4 
 5 import java.util.List;
 6 
 7 /**
 8  * @discription
 9  */
10 public class UnionPay {
11     private List<Bank> bankList = Lists.newArrayList();
12 
13     private List<Company> companyList = Lists.newArrayList();
14 
15     public void register(Object... components) {
16         for (Object component : components) {
17             if (component instanceof Company) {
18                 Company company = (Company) component;
19                 companyList.add(company);
20                 company.register(this);
21             }
22             if (component instanceof Bank) {
23                 Bank bank = (Bank) component;
24                 bankList.add(bank);
25                 bank.register(this);
26             }
27         }
28     }
29 
30     public void sendBank(String msg) {
31         for (Bank bank : bankList) {
32             bank.receiveMsg(msg);
33         }
34     }
35 
36     public void sendCompany(String msg) {
37         for (Company company : companyList) {
38             company.receiveMsg(msg);
39         }
40     }
41 }

主类

 1 package com.example.demo.learn.pattern.behavior.mediator;
 2 
 3 /**
 4  * @discription
 5  */
 6 public class PatternMain {
 7     public static void main(String[] args) {
 8         Bank ccbBank = new CCBBank();
 9         Bank icbcBank = new ICBCBank();
10         Company qianDuCompany = new QianDuCompany();
11         Company daMiCompany = new DaMiCompany();
12         UnionPay unionPay = new UnionPay();
13         unionPay.register(ccbBank, icbcBank, qianDuCompany, daMiCompany);
14         ccbBank.sendMsg("欢迎各位企业来建设银行贷款!");
15         icbcBank.sendMsg("欢迎各位企业来工行洽谈合作!");
16         daMiCompany.sendMsg("哪家银行目前有低息企业贷款?");
17         daMiCompany.sendMsg("哪家银行目前有工资卡优惠活动?");
18     }
19 }

运行主类后,效果如下:

18:58:03.965 [main] WARN com.example.demo.learn.pattern.behavior.mediator.CCBBank - 建设银行发送消息到企业:欢迎各位企业来建设银行贷款!
18:58:03.969 [main] WARN com.example.demo.learn.pattern.behavior.mediator.QianDuCompany - 千度公司收到银行消息:欢迎各位企业来建设银行贷款!
18:58:03.969 [main] WARN com.example.demo.learn.pattern.behavior.mediator.DaMiCompany - 大米公司收到银行消息:欢迎各位企业来建设银行贷款!
18:58:03.970 [main] WARN com.example.demo.learn.pattern.behavior.mediator.ICBCBank - 工商银行发送消息到企业:欢迎各位企业来工行洽谈合作!
18:58:03.970 [main] WARN com.example.demo.learn.pattern.behavior.mediator.QianDuCompany - 千度公司收到银行消息:欢迎各位企业来工行洽谈合作!
18:58:03.970 [main] WARN com.example.demo.learn.pattern.behavior.mediator.DaMiCompany - 大米公司收到银行消息:欢迎各位企业来工行洽谈合作!
18:58:03.970 [main] WARN com.example.demo.learn.pattern.behavior.mediator.DaMiCompany - 大米公司发送消息到银行:哪家银行目前有低息企业贷款?
18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.CCBBank - 建设银行收到企业消息:哪家银行目前有低息企业贷款?
18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.ICBCBank - 工商银行收到企业消息:哪家银行目前有低息企业贷款?
18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.DaMiCompany - 大米公司发送消息到银行:哪家银行目前有工资卡优惠活动?
18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.CCBBank - 建设银行收到企业消息:哪家银行目前有工资卡优惠活动?
18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.ICBCBank - 工商银行收到企业消息:哪家银行目前有工资卡优惠活动?

代码类图如下:

我们可以从类图发现,银行和企业并没有直接关联,他们都是直接耦合中介类,所有的请求和响应都是和中介类进行交互(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )

中介模式的优点是解耦:我们可以直接将第三方提供类进行组织,而不需要修改他们的代码。
缺点也很明显,业务依赖逻辑全部抽离到了中介类中,中介类会过于臃肿。

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

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

相关文章

Large Vision Model

LVM https://yutongbai.com/lvm.html https://zhuanlan.zhihu.com/p/671423679Large Vision Model(简称LVM)是一种纯粹基于视觉数据进行训练和推理的大型模型,其特点在于无需涉及任何自然语言输入或输出。该模型的提出源自一篇由UC Berkeley的三位计算机视觉专家联合撰写的论…

2024 天池云原生编程挑战赛决赛名单出炉,冠军来自中山大学、昆仑数智战队

9 月 20 日,2024 天池云原生编程挑战赛决赛答辩完美落幕,12 支进入决赛的团队用精彩的答辩,为历时 3 个月的大赛画下了圆满的句号。其中,来自中山大学的陈泓仰以及来自昆仑数智的冉旭欣、沈鑫糠、武鹏鹏,以出色的方案、创新的优化思路、过硬的技术实力分获赛道一和赛道二的…

1panle搭建的maxkb增加本地向量模型

首先下载模型,比如m3e-large,并上传到/opt/maxkb/model/local_embedding/ 目录,没有就创建 目录如下:然后修改1panel的容器信息,点击右边的编辑:在下方的挂在目录处点击添加:在两个框都输入: /opt/maxkb/model/local_embedding 然后,确认保存,再重启容器 重启成功后…

WinForm右键菜单的快键键设置

原文链接:https://blog.csdn.net/zhourongxiang1/article/details/138176092 Form中有一个富文本框控件,在里面右键鼠标,弹出下拉菜单。快捷键的效果则是按下alt+p,触发按下属性事件。 1.从工具箱添加RichTextBox2.然后添加ContextMenuStrip 3.选择RichTextBox的ContextMenu…

信息学奥赛复赛复习02-CSP-J2019-02-结构体、无构造函数、有构造函数、初始化列表构造、集合、数组存在性判断

PDF文档公众号回复关键字:202409241 2019 CSP-J 题目2 公交换乘 [题目描述] 著名旅游城市 B 市为了鼓励大家采用公共交通方式出行,推出了一种地铁换乘公交车的优惠方案 在搭乘一次地铁后可以获得一张优惠票,有效期为 45 分钟,在有效期内可以消耗这张优惠票,免费搭乘一次票价…

重磅!阿里云可观测产品家族全新升级,AI +数据双驱动,打造全栈可观测体系

近日,阿里云可观测产品家族正式发布云监控 2.0,隶属产品日志服务 SLS、云监控 CMS、应用实时监控服务 ARMS 迎来重磅升级。借助全新升级的一站式全景接入、统一观测图谱以及 AI 增强的跨域智能洞察能力。引言: 近日,阿里云可观测产品家族正式发布云监控 2.0,隶属产品日志服…

期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟

在 AI 程序员的帮助下,一个几乎没有专业编程经验的初中生,在人头攒动的展台上从零开始,两分钟就做出了一个倒计时网页。在 AI 程序员的帮助下,一个几乎没有专业编程经验的初中生,在人头攒动的展台上从零开始,两分钟就做出了一个倒计时网页。 他需要做的,只是输入包含几句…

Serverless + AI 让应用开发更简单,加速应用智能化

2024 云栖大会开幕,在大会第一天,阿里云正式发布全新产品——云应用开发平台 CAP。CAP 拥有丰富的场景化应用模板,可以极速体验,并且具备更低的成本优势以及灵活组装等特点,成为广大开发者与企业必备的一站式应用开发平台,让应用开发更简单。阿里云云原生应用平台负责人 …

调用微信、支付宝支付逻辑

1.获取sku信息 通过参数app_id: "**" decision_token: "" platform: "web" product_type: "vip"获取支付的种类和 product_id 通过参数{product_id: "302048", pay_channel: "alipay_native", price: 29000, pri…

如何解决海洋CMS数据库安装错误问题?

当遇到海洋CMS数据库安装错误的问题时,可以采取以下步骤来诊断和解决问题: 1. 检查数据库连接信息 确保你在安装过程中输入的数据库连接信息(如主机名、用户名、密码、数据库名)是正确的。如果输入错误,将会导致连接失败。 2. 确认数据库服务器状态 确认MySQL数据库服务正…

在 Windows Server 2022 上架设 WSUS(Windows更新服务)(Windows Server Update Services)服务器的步骤如下:

在 Windows Server 2022 上架设 WSUS(Windows更新服务)(Windows Server Update Services)服务器的步骤如下:1. 安装 WSUS 角色打开服务器管理器:通过开始菜单找到“服务器管理器”,并打开它。添加角色和功能:在服务器管理器中,点击“管理” > “添加角色和功能”。…