zoukankan      html  css  js  c++  java
  • 设计模式--14、中介者模式

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

    类型:行为类模式

    看看结构图的形象描述吧:

    中介者模式的结构

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

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

    为什么要使用中介者模式

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

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

    对于设计模式这个东西,理解了,应该写一个代码体会一下,我们以qq和email发送消息为实例,代码如下:

    package designpatterns;
    
    import java.util.HashMap;
    import java.util.Map.Entry;
    
    /*
     * 中介者模式
     */
    //先抽像一个使用者类(学生)
    abstract class Person {
    	String strName;	//姓名
    	String strType;	//类型
    	//每个人都有一个用来传递信息的中介List,如qq,email等
    	HashMap<String, AbstractMediator> MyMediatorList = new HashMap<String, AbstractMediator>();
    	public Person(String strName){
    		this.strName = strName;
    	}
    	public String getStrName() {
    		return strName;
    	}
    	public void setStrName(String strName) {
    		this.strName = strName;
    	}
    	public String getStrType() {
    		return strType;
    	}
    	public void setStrType(String strType) {
    		this.strType = strType;
    	}
    	public void AddMediator(AbstractMediator MyMediator) {
    		MyMediatorList.put(MyMediator.getStrName(), MyMediator);
    	}
    	//给所有人发消息
    	public void SendMessageToAll(String MediatorName, String strMessage){
    		MyMediatorList.get(MediatorName).SendMessageToAll(strMessage);
    	}
    	//给指定类型的人发消息
    	public void SendMessageByType(String MediatorName, String strType, String strMessage) {
    		MyMediatorList.get(MediatorName).SendMessageByType(strType, strMessage);
    	}
    	//给指定名字的人发消息
    	public void SendMessageByName(String MediatorName, String strName, String strMessage) {
    		MyMediatorList.get(MediatorName).SendMessageByName(strName, strMessage);
    	}
    	//接收消息
    	public void ReciveMessage(String strMessage){
    		System.out.println("[" + strType +"]" + """ + strName + """ + "收到"+strMessage);
    	}
    }
    //定义学生
    class Student extends Person {
    
    	public Student(String strName) {
    		super(strName);
    		strType = "学生";
    	}
    }
    
    //定义老师
    class Teacher extends Person {
    
    	public Teacher(String strName) {
    		super(strName);
    		strType = "老师";
    	}
    }
    //定义校长
    class Principal extends Person {
    
    	public Principal(String strName) {
    		super(strName);
    		strType = "校长";
    	}
    }
    //定义一个抽象中介
    abstract class AbstractMediator {
    	//中介的名字
    	String strName;
    	public AbstractMediator (String strName) {
    		this.strName = strName;
    	}
    	public String getStrName() {
    		return strName;
    	}
    	//定义一个人员列表
    	HashMap<String, Person> PersonList = new HashMap<String, Person>();  
    	public void addPerson(Person onePerson) {
    		PersonList.put(onePerson.getStrName(), onePerson);
    		onePerson.AddMediator(this);
    	}
    	public void deletePerson(String strName) {
    		PersonList.remove(strName);
    	}
    	//给所有人发消息
    	abstract public void SendMessageToAll(String strMessage);
    	//给指定类型的人发消息
    	abstract public void SendMessageByType(String strType, String strMessage);
    	//给指定名字的人发消息
    	abstract public void SendMessageByName(String strName, String strMessage);
    }
    //定义一个中介(QQ)用于传递消息
    class QQMediator extends AbstractMediator{
    
    	public QQMediator(String strName) {
    		super(strName);
    	}
    
    	@Override
    	public void SendMessageToAll(String strMessage) {
    		String strQQMessage = "来自QQ消息:" + strMessage;
    		for(Entry<String, Person> entry : PersonList.entrySet()){
    			entry.getValue().ReciveMessage(strQQMessage);
    		}
    	}
    
    	@Override
    	public void SendMessageByType(String strType, String strMessage) {
    		String strQQMessage = "来自QQ消息:" + strMessage;
    		for(Entry<String, Person> entry : PersonList.entrySet()){
    			if(strType == entry.getValue().getStrType())
    			{
    				entry.getValue().ReciveMessage(strQQMessage);
    			}
    		}
    	}
    
    	@Override
    	public void SendMessageByName(String strName, String strMessage) {
    		String strQQMessage = "来自QQ消息:" + strMessage;
    		PersonList.get(strName).ReciveMessage(strQQMessage);
    	}
    	
    }
    
    //定义一个中介(Email)用于传递消息
    class EmailMediator extends AbstractMediator{
    
    	public EmailMediator(String strName) {
    		super(strName);
    	}
    
    	@Override
    	public void SendMessageToAll(String strMessage) {
    		String strQQMessage = "来自Email消息:" + strMessage;
    		for(Entry<String, Person> entry : PersonList.entrySet()){
    			entry.getValue().ReciveMessage(strQQMessage);
    		}
    	}
    
    	@Override
    	public void SendMessageByType(String strType, String strMessage) {
    		String strQQMessage = "来自Email消息:" + strMessage;
    		for(Entry<String, Person> entry : PersonList.entrySet()){
    			if(strType == entry.getValue().getStrType())
    			{
    				entry.getValue().ReciveMessage(strQQMessage);
    			}
    		}
    	}
    
    	@Override
    	public void SendMessageByName(String strName, String strMessage) {
    		String strQQMessage = "来自Email消息:" + strMessage;
    		PersonList.get(strName).ReciveMessage(strQQMessage);
    	}
    	
    }
    public class Mediator {
    
    	public static void main(String[] args) {
    		//定义两个学生
    		Student student1 = new Student("学生一");
    		Student student2 = new Student("学生二");
    		//定义两个老师
    		Teacher teacher1 = new Teacher("老师一");
    		Teacher teacher2 = new Teacher("老师二");
    		//定义两个校长
    		Principal principal1 = new Principal("校长一");
    		Principal principal2 = new Principal("校长二");
    		//定义两个中介(QQ和email)
    		QQMediator myQQ = new QQMediator("qq");
    		EmailMediator myEmail = new EmailMediator("email");
    		//将所有人员分别添加到qq和email中
    		myQQ.addPerson(student1);
    		myQQ.addPerson(student2);
    		myQQ.addPerson(teacher1);
    		myQQ.addPerson(teacher2);
    		myQQ.addPerson(principal1);
    		myQQ.addPerson(principal2);
    		myEmail.addPerson(student1);
    		myEmail.addPerson(student2);
    		myEmail.addPerson(teacher1);
    		myEmail.addPerson(teacher2);
    		myEmail.addPerson(principal1);
    		myEmail.addPerson(principal2);
    		//下面开始进行通信
    		//首先"校长一"通过qq向"校长二"发一条消息
    		principal1.SendMessageByName("qq", "校长二", "你觉得什么时候放假好?");
    		principal2.SendMessageByName("qq", "校长一", "从明天开始放假吧!");
    		principal1.SendMessageByName("qq", "校长二", "好的,那我发通知了");
    		//然后"校长一"通过email向所有人员发一条消息
    		principal1.SendMessageByType("email", "老师", "老师们都注意了,从明天开始放假");
    		//老师收到消息后再给学生发消息
    		teacher1.SendMessageByType("email", "学生", "同学们都注意了,从明天开始放假了!");
    		//学生收到消息后,开始qq聊起来了
    		student1.SendMessageByName("qq", "学生二", "明天放假了,我们去哪玩啊?");
    		student2.SendMessageByName("qq", "学生一", "我们去爬山吧,再问问还有没有别人去!");
    		student2.SendMessageToAll("email", "明天我们去爬山,还有没有一起去的?");
    	}
    
    }
    

      

    二、使用中介者模式的场合和优缺点

    使用终结者模式的场合

    1.一组定义良好的对象,现在要进行复杂的通信。

    2.定制一个分布在多个类中的行为,而又不想生成太多的子类。

    可以看出,中介对象主要是用来封装行为的,行为的参与者就是那些对象,但是通过中介者,这些对象不用相互知道。呵呵~~~

    使用中介者模式的优点:

    1.降低了系统对象之间的耦合性,使得对象易于独立的被复用。

    2.提高系统的灵活性,使得系统易于扩展和维护。

    使用中介者模式的缺点:

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

  • 相关阅读:
    assign()与create()的区别
    ES6对象扩展——部分新的方法和属性
    ES6对象扩展——扩展运算符
    rest operater剩余操作符
    深拷贝和浅拷贝
    for in和for of的简单区别
    查询ES6兼容的网站
    ES6扩展——对象的扩展(简洁表示法与属性名表达式)
    滚动条设置样式
    marquee横向无缝滚动无js
  • 原文地址:https://www.cnblogs.com/snowbook/p/5163784.html
Copyright © 2011-2022 走看看