Java 设计模式之中介者模式
一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如有六个同事类对象,假如对象1发生变化,会有4个对象受到影响。如果对象2发生变化,那么会有5个对象受到影响。也就是说,同事类之间直接关联的设计是不好的。
如果引入中介者模式,那么同事类之间的关系将变为星型结构,任何一个类的变动,只会影响的类本身,以及中介者,这样就减小了系统的耦合。一个好的设计,必定不会把所有的对象关系处理逻辑封装在本类中,而是使用一个专门的类来管理那些不属于自己的行为。
应用
我们使用一个例子来说明一下什么是同事类:有两个类A和B,类中各有一个数字,并且要保证类B中的数字永远是类A中数字的100倍。也就是说,当修改类A的数时,将这个数字乘以100赋给类B,而修改类B时,要将数除以100赋给类A。类A类B互相影响,就称为同事类。代码如下:
- abstract class AbstractColleague {
- protected int number;
- public int getNumber() {
- return number;
- }
- public void setNumber(int number){
- this.number = number;
- }
- //抽象方法,修改数字时同时修改关联对象
- public abstract void setNumber(int number, AbstractColleague coll);
- }
- class ColleagueA extends AbstractColleague{
- public void setNumber(int number, AbstractColleague coll) {
- this.number = number;
- coll.setNumber(number*100);
- }
- }
- class ColleagueB extends AbstractColleague{
- public void setNumber(int number, AbstractColleague coll) {
- this.number = number;
- coll.setNumber(number/100);
- }
- }
- public class Client {
- public static void main(String[] args){
- AbstractColleague collA = new ColleagueA();
- AbstractColleague collB = new ColleagueB();
- System.out.println("==========设置A影响B==========");
- collA.setNumber(1288, collB);
- System.out.println("collA的number值:"+collA.getNumber());
- System.out.println("collB的number值:"+collB.getNumber());
- System.out.println("==========设置B影响A==========");
- collB.setNumber(87635, collA);
- System.out.println("collB的number值:"+collB.getNumber());
- System.out.println("collA的number值:"+collA.getNumber());
- }
- }
上面的代码中,类A类B通过直接的关联发生关系,假如我们要使用中介者模式,类A类B之间则不可以直接关联,他们之间必须要通过一个中介者来达到关联的目的。
同事类
- abstract class AbstractColleague {
- protected int number;
- public int getNumber() {
- return number;
- }
- public void setNumber(int number){
- this.number = number;
- }
- //注意这里的参数不再是同事类,而是一个中介者
- public abstract void setNumber(int number, AbstractMediator am);
- }
- class ColleagueA extends AbstractColleague{
- public void setNumber(int number, AbstractMediator am) {
- this.number = number;
- am.AaffectB();
- }
- }
- class ColleagueB extends AbstractColleague{
- @Override
- public void setNumber(int number, AbstractMediator am) {
- this.number = number;
- am.BaffectA();
- }
- }
抽象中介者类
- abstract class AbstractMediator {
- protected AbstractColleague A;
- protected AbstractColleague B;
- public AbstractMediator(AbstractColleague a, AbstractColleague b) {
- A = a;
- B = b;
- }
- public abstract void AaffectB();
- public abstract void BaffectA();
- }
中介者类
- class Mediator extends AbstractMediator {
- public Mediator(AbstractColleague a, AbstractColleague b) {
- super(a, b);
- }
- //处理A对B的影响
- public void AaffectB() {
- int number = A.getNumber();
- B.setNumber(number*100);
- }
- //处理B对A的影响
- public void BaffectA() {
- int number = B.getNumber();
- A.setNumber(number/100);
- }
- }
客户端
- public class Client {
- public static void main(String[] args){
- AbstractColleague collA = new ColleagueA();
- AbstractColleague collB = new ColleagueB();
- AbstractMediator am = new Mediator(collA, collB);
- System.out.println("==========通过设置A影响B==========");
- collA.setNumber(1000, am);
- System.out.println("collA的number值为:"+collA.getNumber());
- System.out.println("collB的number值为A的10倍:"+collB.getNumber());
- System.out.println("==========通过设置B影响A==========");
- collB.setNumber(1000, am);
- System.out.println("collB的number值为:"+collB.getNumber());
- System.out.println("collA的number值为B的0.1倍:"+collA.getNumber());
- }
- }
虽然代码比较长,但是还是比较容易理解的,其实就是把原来处理对象关系的代码重新封装到一个中介类中,通过这个中介类来处理对象间的关系。
优点
适当地使用中介者模式可以避免同事类之间的过度耦合,使得各同事类之间可以相对独立地使用。
使用中介者模式可以将对象间一对多的关联转变为一对一的关联,使对象间的关系易于理解和维护。
使用中介者模式可以将对象的行为和协作进行抽象,能够比较灵活的处理对象间的相互作用。
总结
在面向对象编程中,一个类必然会与其他的类发生依赖关系,完全独立的类是没有意义的。一个类同时依赖多个类的情况也相当普遍,既然存在这样的情况,说明,一对多的依赖关系有它的合理性,适当的使用中介者模式可以使原本凌乱的对象关系清晰,但是如果滥用,则可能会带来反的效果。一般来说,只有对于那种同事类之间是网状结构的关系,才会考虑使用中介者模式。可以将网状结构变为星状结构,使同事类之间的关系变的清晰一些。
中介者模式是一种比较常用的模式,也是一种比较容易被滥用的模式。对于大多数的情况,同事类之间的关系不会复杂到混乱不堪的网状结构,因此,大多数情况下,将对象间的依赖关系封装的同事类内部就可以的,没有必要非引入中介者模式。滥用中介者模式,只会让事情变的更复杂。
Java 设计模式之中介者模式的更多相关文章
- 折腾Java设计模式之中介者模式
博文原址:折腾Java设计模式之中介者模式 中介者模式 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类通常处理不同类之间的通信,并 ...
- 从中国加入WTO来看Java设计模式:中介者模式
目录 应用场景 中介者模式 定义 意图 主要解决问题 何时使用 优缺点 世界贸易组织WTO 应用场景 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象 想通过一个 ...
- java设计模式之中介者模式
中介者模式 用一个中介对象来封装一系列的对象交互.中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 中介者模式UML图 中介者模式代码 package com ...
- Java 设计模式 之 中介者模式(Mediator)
中介者的功能非常简单,就是封装对象之间的交互. 如果一个对象的操作会引起其他相关对象的变化,或者是某个操作需要引起其他对象的后续或连带操作,而这个对象又不希望自己来处理这些关系,那么久可以找中介者,把 ...
- 18.java设计模式之中介者模式
基本需求 智能家庭包括各种设备,闹钟.咖啡机.电视机.窗帘等 要看电视时,各个设备可以协同工作,自动完成看电视的准备工作,比如流程为:闹铃响起->咖啡机开始做咖啡->窗帘自动落下-> ...
- Java设计模式之《代理模式》及应用场景
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6525527.html 代理模式算是我接触较早的模式,代理就是中介,中间人.法律上也有代理, ...
- Java设计模式 - - 单例模式 装饰者模式
Java设计模式 单例模式 装饰者模式 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 静态代理模式:https://www.cnblogs.com/StanleyBlogs/p/1 ...
- Java 设计模式泛谈&装饰者模式和单例模式
设计模式(Design Pattern) 1.是一套被反复使用.多人知晓的,经过分类编目 的 代码设计经验总结.使用设计模式是为了可重用代码,让代码更容易维护以及扩展. 2.简单的讲:所谓模式就是得到 ...
- java设计模式之Proxy(代理模式)
java设计模式之Proxy(代理模式) 2008-03-25 20:30 227人阅读 评论(0) 收藏 举报 设计模式javaauthorizationpermissionsstringclass ...
随机推荐
- C++ 定位构造
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://yiluohuanghun.blog.51cto.com/3407300/1258 ...
- Working Experience - WPF 中 DataGrid 控件的应用
问题: 添加控件后, 编辑单元格会出现异常 绑定 ItemsSource 属性后, 更新绑定对象的数据, UI 不刷新 如何显示控件中 ComboBox 类型 解决方法: 绑定 ItemsSource ...
- 大话Spark(1)-Spark概述与核心概念
说到Spark就不得不提MapReduce/Hadoop, 当前越来越多的公司已经把大数据计算引擎从MapReduce升级到了Spark. 至于原因当然是MapReduce的一些局限性了, 我们一起先 ...
- SpringMVC中的常用注解
RequestParam 作用: 用于 将请求参数区数据 映射到 功能处理方法的参数上. 属性: value 请求参数中的名称 required 请求参数中是否必须提供此参数. 默认值: ...
- surface shader相关参数,命令
https://docs.unity3d.com/Manual/SL-SurfaceShaders.html 说明: 注意下surfaceshader相关开关选项,input结构体全部可用参数 goo ...
- RenderTexture
https://docs.unity3d.com/Manual/class-RenderTexture.html Size: 图片像素尺寸,这个size可以直接在脚本里通过width和height动态 ...
- 洛谷P1439 排列LCS问题
P1439 排列LCS问题 题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出 ...
- 洛谷P2522 [HAOI2011]Problem b(莫比乌斯反演)
传送门 我们考虑容斥,设$ans(a,b)=\sum_{i=1}^a\sum_{j=1}^b[gcd(a,b)==k]$,这个东西可以和这一题一样去算洛谷P3455 [POI2007]ZAP-Quer ...
- git push error: ! [rejected] failed to push some refs to . . .
报错情况: 报错原因:远程库与本地库不一致造成的,需要把远程库同步到本地库! 解决办法: git pull --rebase origin master 这条指令是将远程库中的更新合并到本地库,--r ...
- 题解 BZOJ 1912 && luogu P3629 [APIO2010]巡逻 (树的直径)
本来抄了篇题解,后来觉得题解都太不友好(我太菜了),一气之下自己打...一打打到第二天QAQ 首先什么边也不加时,总路程就是2*(n-1) 考虑k=1的时候,答案显然是2*(n-1)-直径+1=2*n ...