中介者模式 - 行为模式

时间:2022-03-23 05:10:13
个人理解:    

模式类型:
    Mediator  中介者模式 - 行为模式
    
意图:
    Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
    定义一个中介对象来封装系列对象之间的交互。中介者使各个对象不需要显示地相互引用,从而使其耦合性松散,而且可以独立地改变他们之间的交互。

    
概述:
    中介者模式的本质在于“封装交互”
    中介者模式的目的,就是封装多个对象的交互,这些交互的多在中介者对象里实现。
    只要是实现封装对象的交互,就可以使用中介者模式,不必拘泥于模式结构。

    
角色:
    Mediator:中介者接口。在里面定义了各个同事之间相互交互所需要的方法,可以是公共的方法,如Change方法,也可以是小范围的交互方法。
    ConcreteMediator:具体的中介者实现对象。它需要了解并为维护每个同事对象,并负责具体的协调各个同事对象的交互关系。
    Colleague:同事类的定义,通常实现成为抽象类,主要负责约束同事对象的类型,并实现一些具体同事类之间的公共功能,比如,每个具体同事类都应该知道中介者对象,也就是每个同事对象都会持有中介者对象的引用,这个功能可定义在这个类中。
    ConcreteColleague:具体的同事类,实现自己的业务,需要与其他同事对象交互时,就通知中介对象,中介对象会负责后续的交互。

结构图:
中介者模式 - 行为模式

模式的应用场景:
    According to Gamma et al, the Mediator pattern should be used when:
    a set of objects communicate in well-defined but complex ways. The resulting interdependencies are unstructured and difficult to understand.
    reusing an object is difficult because it refers to and communicates with many other objects.
    a behavior that's distributed between several classes should be customizable without a lot of subclassing.
    
    Examples/实际应用    
    Example 1 - GUI Libraries
    The mediator example is one pattern that is already used in many applications. One of the examples is represented by the Dialog classes in GUI applications frameworks. A Dialog window is a collection of graphic and non-graphic controls. The Dialog class provides the mechanism to facilitate the interaction between controls. For example, when a new value is selected from a ComboBox object a Label has to display a new value. Both the ComboBox and the Label are not aware of each other structure and all the interaction is managed by the Dialog object. Each control is not aware of the existence of other controls.
    
    Example 2 - Chat application
    The chat application is another example of the mediator pattern. In a chat application we can have several participants. It's not a good idea to connect each participant to all the others because the number of connections would be really high, there would be technical problems due to proxies and firewalls, etc... . The most appropriate solution is to have a hub where all participants will connect; this hub is just the mediator class.
    
    1.一组定义良好的对象,现在要进行复杂的通信。
    2.定制一个分布在多个类中的行为,而又不想生成太多的子类。
    可以看出,中介对象主要是用来封装行为的,行为的参与者就是那些对象,但是通过中介者,这些对象不用相互知道。

模式的优缺点:
使用中介者模式的优点:
    1.降低了系统对象之间的耦合性,使得对象易于独立的被复用。
    2.提高系统的灵活性,使得系统易于扩展和维护。
使用中介者模式的缺点:

    中介者模式的缺点是显而易见的,因为这个“中介“承担了较多的责任,所以一旦这个中介对象出现了问题,那么整个系统就会受到重大的影响。


相关模式:
    中介者模式和外观模式
    外观模式多用于封装一个子系统内部的多个模块,目的是向子系统外部提供简单易用的接口。
    中介者模式是提供多个平等的同事对象之间交互关系的封装,一般是用在内部实现上。
    中介者模式和观察者模式
    这两个模式可以组合使用。
    中介者模式可以组合使用观察者模式,来实现当同事对象发生改变时,通知中介对象,让中介对象去进行与其他相关对象的交互。
    
代码(其实读UML图要比代码还要一目了然):

代码分3个部分,第一部分显示2个对象相互交互,第二个代码部分显示使用中介者模式的好处。第三个也是中介者模式,只是数量多一点,使用List保存对象Colleague。

第一部分显示2个对象相互交互

package com.lee.desingerPattener23.mediator.dirty;

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 DirtyClient {
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());
}
}


第二个代码部分显示使用中介者模式的好处。2个对象不直接关联

package com.lee.desingerPattener23.mediator.example1;

// http://lastsoul.iteye.com/blog/1883881
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 MediatorClient {
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());

}
}



第三个也是中介者模式,稍复杂一些,只是数量多一点,使用List保存对象Colleague。

package com.lee.desingerPattener23.mediator.example2;

import java.util.ArrayList;
import java.util.List;

abstract class Colleague {
// 引入中介者
private Mediator mediator;
// 消息
private String message;

public Colleague(Mediator m) {
mediator = m;
}
public Mediator getMediator() {
return mediator;
}

public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
// 发送消息
public abstract void sendMsg();
// 收到消息
public abstract void getMsg(String msg);
// 发送消息 //注意!这个是有参的sendMsg
public void sendMsg(String msg) {
this.message = msg;
mediator.action(this);
}
}

class Colleague1 extends Colleague {
public Colleague1(Mediator m) {
super(m);
}
public void getMsg(String msg) {
System.out.println("Colleague1 has get the message -'" + msg + "'");
}
//注意!这个是无参的sendMsg
public void sendMsg() {
System.out.println("Colleague1 has send the message '" + getMessage()+ "'");
}
}

class Colleague2 extends Colleague {
public Colleague2(Mediator m) {
super(m);
}
public void getMsg(String msg) {
System.out.println("Colleague2 has get the message -'" + msg + "'");
}
public void sendMsg() {
System.out.println("Colleague2 has send the message '" + getMessage()+ "'");
}
}

class Colleague3 extends Colleague {
public Colleague3(Mediator m) {
super(m);
}
public void getMsg(String msg) {
System.out.println("Colleague3 has get the message -'" + msg + "'");
}
public void sendMsg() {
System.out.println("Colleague3 has send the message '" + getMessage()+ "'");
}
}

// 中介者
abstract class Mediator {
// Mediator针对Colleague的一个交互行为
public abstract void action(Colleague sender);
// 加入Colleague对象
public abstract void addCollegue(Colleague colleague);
}

class ConcreteMediator extends Mediator {
private List<Colleague> colleagues = new ArrayList<Colleague>(0);

public void addCollegue(Colleague colleague) {
colleagues.add(colleague);
}
public void action(Colleague actor) {
String msg = actor.getMessage();
// send msg
for (Colleague colleague : colleagues) {
if (colleague.equals(actor)) {
colleague.sendMsg();
break;
}
}
// get msg
for (Colleague colleague : colleagues) {
if (colleague.equals(actor))
continue;
else
colleague.getMsg(msg);
}
}
}

// 测试类
public class MediatorTest {

public static void main(String[] args) {
// 生成中介者 并注入到各个Colleague对象中
Mediator mediator = new ConcreteMediator();
Colleague colleague1 = new Colleague1(mediator);
Colleague colleague2 = new Colleague2(mediator);
Colleague colleague3 = new Colleague3(mediator);

// 注册对象到中介
mediator.addCollegue(colleague1);
mediator.addCollegue(colleague2);
mediator.addCollegue(colleague3);

// Colleague1 触发行为
colleague1.sendMsg("嗨,大家好!");
System.out.println();
// Colleague2 触发行为
colleague2.sendMsg("很高兴见到你!");
System.out.println();
// Colleague3 触发行为
colleague3.sendMsg("我们一起玩游戏吧!");
System.out.println();
}
}


所有模式:
    创建型模式,共五种:工厂方法模式、抽象工厂模式单例模式建造者模式原型模式
结构型模式,共七种:适配器模式装饰器模式代理模式外观模式桥接模式组合模式享元模式
行为型模式,共十一种:策略模式模板方法模式观察者模式迭代子模式责任链模式命令模式备忘录模式状态模式访问者模式中介者模式解释器模式
补充模式:空对象模式


参考/转自:
    http://www.cnblogs.com/xudong-bupt/p/3617860.html
    http://www.cnblogs.com/zxj159/p/3466115.html
    http://blog.csdn.net/chenhuade85/article/details/8141831
     http://www.oodesign.com/mediator-pattern.html


转载请注明:     http://blog.csdn.net/paincupid/article/details/46991371