世界需要和平--中介者模式

1.1 世界需要和平

        "你想呀,国与国之间的关系,就类似于不同的对象与对象之间的关系,这就要求对象之间需要知道其他所有对象,尽管将一个系统分割成许多对象通常可以增加其可复用性,但是对象间相互连接的激增又会降低其可复用性了。你知道为什么会这样?"
        "我想是因为大量的连接使得一个对象不可能在没有其他对象的支持下工作,系统表现为一个不可分割的整体,所以,对系统的行为进行任何较大的改动就十分困难了。"

        "总结得很好嘛,要解决这样的问题,可以应用什么原则?"
"我记得之前讲过的叫'迪米特法则',如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。在这里,你的意思就是说,国与国之间完全可以通过'联合国'这个中介者来发生关系,而不用直接通信。"


        "是呀,通过中介者对象,可以将系统的网状结构变成以中介者为中心的星状结构,每个具体对象不再通过直接的联系与另一个对象发生相互作用,而是通过'中介者'对象与另一个对象发生相互作用。中介者对象的设计,使得系统的结构不会因为新对象的引入造成大量的修改工作。"
        "当时你对我解释'迪米特法则'的时候,是以我们公司的IT部门的管理为例子的,其实让我一个刚进公司的人去求任何一个不认识的IT部同事帮忙是有困难的,但如果是有IT主管来协调工作,就不至于发生我第一天上班却没有电脑进行工作的局面。IT主管就是一个'中介者'对象了。"

1.2  中介者模式

        中介者模式(Mediator),用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。[DP]
中介者模式(Mediator)结构图

package code.chapter25.mediator0;public class Test {public static void main(String[] args) {System.out.println("**********************************************");       System.out.println("《大话设计模式》代码样例");System.out.println(); ConcreteMediator m = new ConcreteMediator();ConcreteColleague1 c1 = new ConcreteColleague1(m);ConcreteColleague2 c2 = new ConcreteColleague2(m);m.setColleague1(c1);m.setColleague2(c2);c1.send("吃过饭了吗?");c2.send("没有呢,你打算请客?");System.out.println();System.out.println("**********************************************");}
}//中介者类
abstract class Mediator{//定义一个抽象的发送消息方法,得到同事对象和发送信息public abstract void send(String message,Colleague colleague);
}abstract class Colleague {protected Mediator mediator;//构造方法,得到中介者对象public Colleague(Mediator mediator){this.mediator = mediator;}
}class ConcreteColleague1 extends Colleague {public ConcreteColleague1(Mediator mediator) {super(mediator);}public void send(String message) {this.mediator.send(message, this);}public void notify(String message) {System.out.println("同事1得到信息:" + message);}
}class ConcreteColleague2 extends Colleague {public ConcreteColleague2(Mediator mediator) {super(mediator);}public void send(String message){this.mediator.send(message, this);}public void notify(String message){System.out.println("同事2得到信息:" + message);}
}class ConcreteMediator extends Mediator{private ConcreteColleague1 colleague1;private ConcreteColleague2 colleague2;public void setColleague1(ConcreteColleague1 value) {this.colleague1 = value; }public void setColleague2(ConcreteColleague2 value) {this.colleague2 = value; }public void send(String message, Colleague colleague){if (colleague == colleague1) {colleague2.notify(message);}else {colleague1.notify(message);}}
}


"Colleague叫作抽象同事类,而ConcreteColleague是具体同事类,每个具体同事只知道自己的行为,而不了解其他同事类的情况,但他们却都认识中介者对象,Mediator是抽象中介者,定义了同事对象到中介者对象的接口,ConcreteMediator是具体中介者对象,实现抽象类的方法,它需要知道所有具体同事类,并从具体同事接收消息,向具体同事对象发出命令。"
Colleague类:抽象同事类。
ConcreteColleague1和ConcreteColleague2等各种同事对象:
Mediator类:抽象中介者类。
ConcreteMediator类:具体中介者类。

        "由于有了Mediator,使得ConcreteColleague1和ConcreteColleague2在发送消息和接收信息时其实是通过中介者来完成的,这就减少了它们之间的耦合度了。"大鸟说,"好了,该你来练习了,需求是美国和伊拉克之间的对话都是通过联合国安理会作为中介来完成。"
        "哦,这应该没什么大问题,美国和伊拉克都是国家,有一个国家抽象类和两个具体国家类就可以了。但'联合国'到底是Mediator还是ConcreteMediator呢?"
        "这要取决于未来是否有可能扩展中介者对象,比如你觉得联合国除了安理会,还有没有可能有其他机构存在呢?"
        "联合国的机构还有如国际劳工组织、教科文组织、世界卫生组织、世界贸易组织等,很多的,所以Mediator应该是'联合国机构',而'安理会'是一个具体的中介者。"
"很好,如果不存在扩展情况,那么Mediator可以与ConcreteMediator合二为一。

1.3 安理会作中介

package code.chapter25.mediator1;public class Test {public static void main(String[] args) {System.out.println("**********************************************");       System.out.println("《大话设计模式》代码样例");System.out.println(); UnitedNationsSecurityCouncil UNSC = new UnitedNationsSecurityCouncil();USA c1 = new USA(UNSC);Iraq c2 = new Iraq(UNSC);UNSC.setUSA(c1);UNSC.setIraq(c2);c1.declare("不准研制核武器,否则要发动战争!");c2.declare("我们没有核武器,也不怕侵略。");System.out.println();System.out.println("**********************************************");}
}abstract class Country {protected UnitedNations unitedNations;public Country(UnitedNations unitedNations){this.unitedNations = unitedNations;}
}class USA extends Country {public USA(UnitedNations unitedNations) {super(unitedNations);}public void declare(String message) {this.unitedNations.declare(message, this);}public void getMessage(String message) {System.out.println("美国获得对方信息:" + message);}
}class Iraq extends Country {public Iraq(UnitedNations unitedNations) {super(unitedNations);}public void declare(String message) {this.unitedNations.declare(message, this);}public void getMessage(String message) {System.out.println("伊拉克获得对方信息:" + message);}
}//中介者类
abstract class UnitedNations{//声明public abstract void declare(String message,Country country);
}//联合国安理会
class UnitedNationsSecurityCouncil extends UnitedNations{private USA countryUSA;private Iraq countryIraq;public void setUSA(USA value) {this.countryUSA = value; }public void setIraq(Iraq value) {this.countryIraq = value; }public void declare(String message, Country country){if (country == this.countryUSA) {this.countryIraq.getMessage(message);}else if (country == this.countryIraq) {this.countryUSA.getMessage(message);}}
}

        "我觉得尽管这样的设计可以减少了ConcreteColleague类之间的耦合,但这又使得ConcreteMediator责任太多了,如果它出了问题,则整个系统都会有问题了。"

1.4 中介者的优缺点

        "说得好,如果联合国安理会出了问题,当然会对世界都造成影响。所以说,中介者模式很容易在系统中应用,也很容易在系统中误用。当系统出现了'多对多'交互复杂的对象群时,不要急于使用中介者模式,而要先反思你的系统在设计上是不是合理。你来总结一下中介者模式的优缺点吧。"
        "我觉得中介者模式的优点首先是Mediator的出现减少了各个Colleague的耦合,使得可以独立地改变和复用各个Colleague类和Mediator,比如任何国家的改变不会影响到其他国家,而只是与安理会发生变化。其次,由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到它们之间的交互上来,也就是站在一个更宏观的角度去看待系统。比如巴以冲突,本来只能算是国与国之间的矛盾,因此各自的看法可能都比较狭隘,但站在联合国安理会的角度,就可以从全球化、也更客观的角度来看待这个问题,在调停和维和上做出贡献。"
        "用中介者模式的确可以从更宏观的角度来看待问题。那中介者模式的缺点呢?"
        "就是你刚才提到的,具体中介者类ConcreteMediator会因为ConcreteColleague越来越多,而变得非常复杂,反而不容易维护了。"
        "是的,由于ConcreteMediator控制了集中化,于是就把交互复杂性变为中介者的复杂性,这就使得中介者会变得比任何一个ConcreteColleague都复杂。事实上,联合国安理会秘书长的工作应该是非常繁忙的,谁叫他就是'全球最大的官'呢。也正因为此,中介者模式的优点来自集中控制,其缺点也是它,使用时要考虑清楚哦。"
        "你平时用.NET写的Windows应用程序中的Form或Web网站程序的aspx就是典型的中介者呀。"

        "比如计算器程序,它上面有菜单控件、文本控件、多个按钮控件和一个Form窗体,每个控件之间的通信都是通过谁来完成的?它们之间是否知道对方的存在?"
        "哦,我知道了,每个控件的类代码都被封装了,所以它们的实例是不会知道其他控件对象的存在的,比如单击数字按钮要在文本框中显示数字,按照我以前的想法就应该要在Button类中编写给TextBox类实例的Text属性赋值的代码,造成两个类有耦合,这显然是非常不合理的。但实际情况是它们都有事件机制,而事件的执行都是在Form窗体的代码中完成,也就是说,所有的控件交互都是由Form窗体来作中介,操作各个对象,这的确是典型的中介者模式应用。"
        "中介者模式一般应用于一组对象以定义良好但是复杂的方式进行通信的场合,比如刚才得到的窗体Form对象或Web页面aspx,以及想定制一个分布在多个类中的行为,而又不想生成太多的子类的场合。"
        "我相信如果所有的国际安全问题都上升到安理会来解决,世界将不再有战争,世界将会永远和平。让世界充满爱,世界呼唤和平。"

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

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

相关文章

MySQL中的存储过程详解(上篇)

使用语言 MySQL 使用工具 Navicat Premium 16 代码能力快速提升小方法,看完代码自己敲一遍,十分有用 拖动表名到查询文件中就可以直接把名字拉进来中括号,就代表可写可不写 目录 1.认识存储过程 1.1 存储过程的作用 1.2 存储过程简介…

【word】文档标题如何自动编号

我在写一个word文档的时候,每一级标题的格式都设置好了,包括字体,大小等等,但是如何自动编号呢? 在写中期报告的时候,我对每一级标题的格式都创建了一个单独的样式,像这样: 对于每一…

数据类型知识

1,介绍 根据数据所占的空间不同,把数据分为不同的数据类型 js的变量数据类型是在程序运行中,靠等号右边数值的值来判断的 js动态变量,里面的数据类型是可以变化的 2.数据类型 1.简单数据类型 程序里面,数字前面有…

plotly绘图——热力图

文章目录 介绍热力图基础热力图代码解释 多热力图代码解释 显示数字的热力图代码解释 介绍 plotly是一个易于使用,功能强大的python绘图库,用于构建可交互式的图表(可以自行运行后使用鼠标拖拽图片试试),本系列文章将介…

基于springboot+vue的企业人事管理设计与实现

前言 基于Java的企业人事管理设计与实现,可以让用户在最短的时间里享受到最好的服务;而开发本系统,又能够提高系统整体工作水平,简化工作程序,这对管理员和员工来说都是一件非常乐意的事情。 本系统针对基于Java的企…

(一)Jetpack Compose 从入门到会写

基本概念 Compose 名称由来 众所周知,继承在功能拓展上表现的很脆弱,容易类、函数爆炸,通过代理和包装进行组合会更健壮。 Compose 意为组合,使用上也是把 Compose 函数以 模拟函数调用层级关系的方式 组合到一起,最终…

Vue.js------vue基础

1. 能够了解更新监测, key作用, 虚拟DOM, diff算法2. 能够掌握设置动态样式3. 能够掌握过滤器, 计算属性, 侦听器4. 能够完成品牌管理案例 一.Vue基础_更新监测和key 1.v-for更新监测 目标:目标结构变化, 触发v-for的更新 情况1: 数组翻转情况2: 数组截取情况3…

记录--病理切片图像处理

简介 数字病理切片,也称为全幻灯片成像(Whole Slide Imaging,WSI)或数字切片扫描,是将传统的玻片病理切片通过高分辨率扫描仪转换为数字图像的技术。这种技术对病理学领域具有革命性的意义,因为它允许病理…

C语言文件操作详解

1. 什么是文件: 文件是计算机中存储数据的一种方式,它可以包含文本、图像、音频、视频等各种形式的信息。在计算机系统中,文件被组织成一个个独立的单元,可以通过文件名来标识和访问。文件可以存储在计算机的硬盘、固态硬盘、光盘…

SWM341系列应用(RTC、FreeRTOS\RTTHREAD应用和Chip ID)

SWM341系列RTC应用 22.1、RTC的时钟基准 --liuzc 2023-8-17 现象:客户休眠发现RTC走的不准,睡眠2小时才走了5分钟。 分析与解决:经过排查RTC的时钟源是XTAL_32K,由于睡眠时时设置XTAL->CR0;,会把XTAL_32K给关…

【Canvas与艺术】绘制磨砂黄铜材质Premium Quality徽章

【关键点】 渐变色的使用、斜纹的实现、底图的寻觅 【成果图】 ​​​​​​​ 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><tit…

C++ PTA 天梯赛 L1-003 个位数统计 L1-005 考试座位号 【范围for循环】【. 与 -> 访问成员】

L1-003 个位数统计 最后一个测试点考察的是当N特别大时&#xff0c;如果用整数存会数据溢出&#xff0c;改成字符串可以增大范围 知识点&#xff1a; 1.范围 for 循环&#xff0c;它对于遍历容器&#xff08;比如字符串&#xff09;中的元素非常方便。在这里&#xff0c;N 是…

TinyEMU源码分析之中断处理

TinyEMU源码分析之中断处理 1 触发中断2 查询中断2.1 查询中断使能与pending状态&#xff08;mie和mip&#xff09;2.2 查询中断总开关与委托&#xff08;mstatus和mideleg&#xff09;2.2.1 M模式2.2.2 S模式2.2.3 U模式 3 处理中断3.1 获取中断编号3.2 检查委托3.3 进入中断3…

⑤-1 学习PID--什么是PID

​ PID 算法可以用于温度控制、水位控制、飞行姿态控制等领域。后面我们通过PID 控制电机进行说明。 自动控制系统 在直流有刷电机的基础驱动中&#xff0c;如果电机负载不变&#xff0c;我们只要设置固定的占空比&#xff08;电压&#xff09;&#xff0c;电机的速度就会稳定在…

HTML5 新增语义标签及属性

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 ✍HTML5 新增语义标签及属性&#x1f48e;1 HTML5 新增的块级语义化标签&…

使用ADO.NET访问数据库

目录 访问数据库的步骤 &#xff11;、建立数据库 &#xff12;、设置链接参数 &#xff08;1&#xff09;web网页和数据库连接的方法一 &#xff08;2&#xff09;web网页和数据库连接的方法二 &#xff13;、建立链接对象 &#xff14;、显示数据库 &#xff15;、数…

openwrt局域网配置多个IP

在局域网配置过程中&#xff0c;若是DHCP服务器关闭&#xff0c;又忘记了配置的ip&#xff0c;将很难访问到路由器重新进行配置。这种情况可以在路由器出厂时做一个备用ip去避免。 1.配置 以下是备用ip的配置方法&#xff0c;以SKYLAB的SKW99 WIFI模组为例进行说明&#xff1…

Android使用shape属性绘制边框内渐变色

目录 先上效果图实现方法shape属性介绍代码结果 先上效果图 这是使用AndroidStudio绘制的带有渐变色的边框背景色 实现方法 项目中由于UI设计需求&#xff0c;需要给按钮、控件设置带有背景色效果的。以下是UI效果图。 这里我们使用shape属性来绘制背景效果。 shape属性介…

ffmpeg命令与批处理编程

(一) CMD脚本查找所有文件 powershell与cmd转换 powershell与cmd虽然同为windows命令&#xff0c;但许多命令并不通用。 CMD换行符 a 在CMD下&#xff0c;可以用^作为换行符&#xff0c;类似于Linux下的\。举例如下&#xff1a; start pemu.exe ^ -net nic,vlan1,macaddr…

最新版IntelliJ IDEA 2024.1安装和配置教程 详细图文解说版安装教程

IntelliJ IDEA 2024.1 最新版如何快速入门体验?IntelliJ IDEA 2024.1 安装和配置教程 图文解说版 文章目录 IntelliJ IDEA 2024.1 最新版如何快速入门体验?IntelliJ IDEA 2024.1 安装和配置教程 图文解说版前言 第一步&#xff1a; IntelliJ IDEA 2024.1安装教程第 0 步&…