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 ...
随机推荐
- linux消息队列相关操作
/* 发送消息队列 */ #include <stdio.h>#include <stdlib.h>#include <string.h>#include < ...
- 洛谷P3379 【模板】最近公共祖先(LCA)(dfs序+倍增)
P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...
- HDU - 4804 Campus Design(状压+轮廓线dp)
Campus Design Nanjing University of Science and Technology is celebrating its 60th anniversary. In o ...
- 安装coreseek 编译错误
Ubuntu下 编译csft 报错fatal error python.h no such file or directory 执行apt-get install python-dev即可
- 如何使用Xshell连接VMware上的Linux虚拟机
前序:最近开始研究Hadoop平台的搭建,故在本机上安装了VMware workstation pro,并创建了Linux虚拟机(centos系统),为了方便本机和虚拟机间的切换,准备使用Xshell ...
- Vuex有哪些作用
1.Vuex实现路由数据通讯 点击跳转路由的时候,把写入vuex,跳转后取出vuex
- ·ios 圆角
uiview 直接设置 view.layer.cornerRadius = 5 uiimageview 还需要在设置view.layer.masksToBounds = true .uiview设置这 ...
- VLAN-8-VTP配置
未配置域名的服务器不会发送任何VTP更新.
- CC13:回文链表
题目 请编写一个函数,检查链表是否为回文. 给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文. 测试样例: {1,2,3,2,1} 返回:true {1,2,3,2, ...
- [LOJ3054] 「HNOI2019」鱼
[LOJ3054] 「HNOI2019」鱼 链接 链接 题解 首先想 \(O(n^3)\) 的暴力,不难发现枚举 \(A\) 和 \(D\) 后, \((B,C)\) 和 \((E,F)\) 两组点互 ...