关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » 算法设计 »23种设计模式之中介者模式

    23种设计模式之中介者模式

    2015-04-03 00:00:00 出处:ImportNew
    分享

    定义:用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。

    类型:行为类模式

    类图:

    23种设计模式(7):中介者模式

    中介者模式的结构

    中介者模式又称为调停者模式,从类图中看,共分为3部分:

    抽象中介者:定义好同事类对象到中介者对象的接口,用于各个同事类之间的通信。一般包括一个或几个抽象的事件方法,并由子类去实现。 中介者实现类:从抽象中介者继承而来,实现抽象中介者中定义的事件方法。从一个同事类接收消息,然后通过消息影响其他同时类。 同事类:如果一个对象会影响其他的对象,同时也会被其他对象影响,那么这两个对象称为同事类。在类图中,同事类只有一个,这其实是现实的省略,在实际应用中,同事类一般由多个组成,他们之间相互影响,相互依赖。同事类越多,关系越复杂。并且,同事类也可以表现为继承了同一个抽象类的一组实现组成。在中介者模式中,同事类之间必须通过中介者才能进行消息传递。

    为什么要使用中介者模式

    一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如在下图中,有六个同事类对象,如果对象1发生变化,那么将会有4个对象受到影响。如果对象2发生变化,那么将会有5个对象受到影响。也就是说,同事类之间直接关联的设计是不好的。

    23种设计模式(7):中介者模式

    23种设计模式(7):中介者模式

    如果引入中介者模式,那么同事类之间的关系将变为星型结构,从图中可以看到,任何一个类的变动,只会影响的类本身,以及中介者,这样就减小了系统的耦合。一个好的设计,必定不会把所有的对象关系处理逻辑封装在本类中,而是使用一个专门的类来管理那些不属于自己的行为。

    23种设计模式(7):中介者模式

    我们使用一个例子来说明一下什么是同事类:有两个类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());
    
    	}
    }

    虽然代码比较长,但是还是比较容易理解的,其实就是把原来处理对象关系的代码重新封装到一个中介类中,通过这个中介类来处理对象间的关系。

    中介者模式的优点

    适当地使用中介者模式可以避免同事类之间的过度耦合,使得各同事类之间可以相对独立地使用。 使用中介者模式可以将对象间一对多的关联转变为一对一的关联,使对象间的关系易于理解和维护。 使用中介者模式可以将对象的行为和协作进行抽象,能够比较灵活的处理对象间的相互作用。

    适用场景

    在面向对象编程中,一个类必然会与其他的类发生依赖关系,完全独立的类是没有意义的。一个类同时依赖多个类的情况也相当普遍,既然存在这样的情况,说明,一对多的依赖关系有它的合理性,适当的使用中介者模式可以使原本凌乱的对象关系清晰,但是如果滥用,则可能会带来反的效果。一般来说,只有对于那种同事类之间是网状结构的关系,才会考虑使用中介者模式。可以将网状结构变为星状结构,使同事类之间的关系变的清晰一些。

    中介者模式是一种比较常用的模式,也是一种比较容易被滥用的模式。对于大多数的情况,同事类之间的关系不会复杂到混乱不堪的网状结构,因此,大多数情况下,将对象间的依赖关系封装的同事类内部就可以的,没有必要非引入中介者模式。滥用中介者模式,只会让事情变的更复杂。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    商业智能成CIO优先关注点 技术落地方显成效(1)

    用linux安装MySQL时产生问题破解

    JAVA中关于Map的九大问题

    windows 7旗舰版无法使用远程登录如何开启telnet服务

    Android View 事件分发机制详解

    MySQL用户变量的用法

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。