2018.3.12 设计模式之中介者模式

时间:2022-10-01 19:42:21

中介模式详解

定义:中介者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用。从而使他们可以松散耦合。当某些对象之间的相互作用发生改变时
不会立即影响其他的一些对象之间的作用。保证这些作用可以彼此独立的作用。

中介者中用到的相关类

Meditor  抽象中介者角色,定义了同时对象到中介者对象的接口,一般以抽象类的方式实现。
ContreteMeditor :具体抽象者角色,继承与中介者,实现了父类定义的方法,他从具体的同事对象接受消息,想具体同时对象发出命令
Colleague :抽象同事类角色,定义了中介者对象的接口,他只知道中介者而不知道其他的同事对象。
ConcreteColleague1、ConcreteColleague2  :具体同事类,继承于抽象同事类,每个具体同事类都知道本身在小范围的行为,而不知道在大范围内的目的。

中介模式通用代码

Colleague.java

package com.gult.demo22;

/**
 * 抽象同事类
 * @author qichunlin
 *
 */
public abstract class Colleague {
    protected Mediator mediator;//抽象中介者
    //get set方法
    public Mediator getMediator() {
        return mediator;
    }
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }
    
    //操作方法
    public abstract void operation();
}

ConcreteColleague.java

package com.gult.demo22;

public class ConcreteColleague extends Mediator{

    public ConcreteColleague(Colleague colleagueA, Colleague colleagueB) {
        super(colleagueA, colleagueB);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void notifyColleagueA() {
        if(colleagueA!=null) {
            colleagueA.operation();
        }
    }

    @Override
    public void notifyColleagueB() {
        if(colleagueB!=null) {
            colleagueB.operation();
        }
    }

}

ConcreteColleagueA.java

package com.gult.demo22;

/**
 * 具体同事类
 * ConcretetColleagueA
 * @author qichunlin
 *
 */
public class ConcreteColleagueA extends Colleague{
    public void notifyColleagueB() {
        mediator.notifyColleagueB();
    }

    @Override
    public void operation() {
        System.out.println("This is ConcreteColleagueA's operation");
    }
    
    
}

ConcreteColleagueB.java

package com.gult.demo22;

/**
 * 具体同事类
 * @author qichunlin
 *
 */
public class ConcreteColleagueB extends Colleague{
    public void notifyColleagueA() {
        mediator.notifyColleagueA();
    }
    @Override
    public void operation() {
        System.out.println("This is ConcreteColleagueB's operation");
    }

}

Mediator.java

package com.gult.demo22;

/**
 * 抽象中介者角色
 * @author qichunlin
 *
 */
public abstract class Mediator {
    protected Colleague colleagueA;//同事1
    protected Colleague colleagueB;//同事2
    
    //有参构造方法
    public Mediator(Colleague colleagueA,Colleague colleagueB) {
        this.colleagueA = colleagueA;
        this.colleagueB = colleagueB;
    }
    
    public abstract void notifyColleagueA();
    public abstract void notifyColleagueB();
}

Test.java

package com.gult.demo22;

/**
 * ceshilei
 * @author qichunlin
 *
 */
public class Test {
    public static void main(String[] args) {
        Colleague colleagueA = new ConcreteColleagueA();
        Colleague colleagueB = new ConcreteColleagueB();
        
        Mediator mediator = new ConcreteColleague(colleagueA, colleagueB);
        colleagueA.setMediator(mediator);
        colleagueB.setMediator(mediator);
        
        ((ConcreteColleagueA)colleagueA).notifyColleagueB();
        ((ConcreteColleagueB)colleagueB).notifyColleagueA();
    }
}

我们通过聊天室实例来演示中介者模式。实例中,多个用户可以向聊天室发送消息,聊天室向所有的用户显示消息。我们将创建两个类 ChatRoom 和 User。User 对象使用 ChatRoom 方法来分享他们的消息。

MediatorPatternDemo,我们的演示类使用 User 对象来显示他们之间的通信。

ChatRoom.java

package com.gult.demo12;

import java.util.Date;

/**
 * 创建中介类
 * 
 * @author qichunlin
 *
 */
public class ChatRoom {
    public static void showMessage(User user,String message) {
        System.out.println(new Date().toString()+" ["+user.getName()+"] "+message);
    }
}

User.java

package com.gult.demo12;

/**
 *创建一个用户
 * 
 * @author qichunlin
 *
 */
public class User {
    private String name;//名字

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public User(String name) {
        this.name = name;
    }
    
    public void sendMessage(String message) {
        ChatRoom.showMessage(this, message);
    }
    
    @Override
    public String toString() {
        return "User [name=" + name + "]";
    }
    
}

MediatorPatternTest.java

package com.gult.demo12;

/**
 * 使用User 对象来显示他们之间的通信
 * 
 * 中介者模式
 * @author qichunlin
 *
 */
public class MediatorPatternTest {
    public static void main(String[] args) {
        //创建两个用户
        User rebert = new User("Rebert");
        User john = new User("John");
        
        rebert.sendMessage("Hi,John");
        john.sendMessage("Hi,Rebert");
    }
}

中介者模式的优缺点

优点:
        简化了对象之间的关系,将系统的各个对象之间的相互关系进行封装,将各个同事类解耦,使得系统变为松耦合
        使用中介者模式可以将对象的行为和协作进行抽象,能够比较灵活的处理对象间的作用
        使用中介者模式可以将对象间多对多的关联转变为一对多的关联,使对象间的关系易于理解和维护。
缺点:
        (1)中介者模式,中介者角色承担了较多的责任,所以一旦这个中介者对象出现了问题,整个系统将会受到重大的影响。
        (2)新增加一个同事类时,不得不去修改抽象中介类和具体中介类,此时可以观察者模式和状态模式来解决这个问题

中介者模式的适用场景

(1)一组定义良好对象,现在要进行复杂的通信。
(2)想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类;
(3)当对象之间的交操作很多且每个对象的行为操作都以来彼此时,为防止在修改一个对象时,同时涉及很多其他对象的行为,可以使用中介者模式