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 ...
随机推荐
- SQL 分割字符串
USE [AppCloud] GO /****** Object: UserDefinedFunction [dbo].[splitstr] Script Date: 12/19/2013 09:33 ...
- ACM-ICPC2018徐州网络赛 Hard to prepare(dp)
Hard to prepare 28.63% 1000ms 262144K After Incident, a feast is usually held in Hakurei Shrine. T ...
- HDU - 3899 JLUCPC(树形dp求距离和)
JLUCPC Dr. Skywind and Dr. Walkoncloud are planning to hold the annual JLU Collegiate Programming Co ...
- Python 获取页面title
#!/usr/bin/python #coding=utf- #urllib2是python自带的模块,在python3.x中被改为urllib.request import urllib.reque ...
- Linux命令 查看Linux版本和是否联网
1.查看Linux内核版本 1.1 $ cat /proc/version [heima01@heima01 ~]$ cat /proc/version Linux version 2.6.32-57 ...
- [设计模式]JDK中的设计模式
转载自:http://blog.csdn.net/gtuu0123/article/details/6114197 本文主要是归纳了JDK中所包含的设计模式,包括作用和其设计类图. 首先来个总结,具体 ...
- Linux —— GDB调试程序
调试实现 在可执行文件中加入源代码的信息,比如可执行文件中第几条机器指令对应源代码的第几行,但并不是把整个源文件嵌入到可执行文件中,所以在调试时必须保证gdb能找到源文件. 生成可执行文件命令: g+ ...
- codeforcesRound378C-dfs+树状数组
分成K个块,每个块内部dfs解决,然后用树状数组统计第i个元素前面有多少怪物已经消失,来计算当前的下标 #include<bits/stdc++.h> #define inf 0x3f3f ...
- CentOS,net core2 sdk nginx、supervisor、mysql
CentOS下 .net core2 sdk nginx.supervisor.mysql环境搭建 作为.neter,看到.net core 2.0的正式发布,心里是有点小激动的,迫不及待的体验了一把 ...
- (转)生产环境常见的HTTP状态码列表(老男孩整理)
生产环境常见的HTTP状态码列表(老男孩整理) 原文:http://blog.51cto.com/oldboy/716294 ##################################### ...