【设计模式二十一之中介者模式】中介者模式详解

中介者模式Mediator Pattern

  • 细说中介者模式
    • 细说中介者模式
      • 定义
      • UML模型
        • 基于UML的代码
      • 场景一
        • 场景
        • 代码
      • 场景二
        • 场景
        • 代码
      • 中介者模式应用和注意事项

细说中介者模式

提示:
博主:章飞 _906285288的博客
博客地址:http://blog.csdn.net/qq_29924041


细说中介者模式

生活中能离开中介这个职业么???答案当然是离开不了啊,如果你想租个房子,你要找类似链家,悟空租房等等一些中介吧,如果你要买二手房的话,你要找个二手房中介帮你找房子吧。所以生活中,其实也其实是到处充斥着中介。

定义

定义:中介者模式其实就是用一个中介对象去封装一系列的对象交互,中介者对象让各个对象不用去显示的去交互从而使其耦合松散,同时也可以独立的改变他们之间的交互的特性

其实可以很好的理解,如果你租房的话,直租的形式是你直接和房东去打交道,但是如果添加了中介的话,这个时候你只需要和中介打交道,然后让中介再去和房东打交道,这一点上主要表现在现在的租房代理商,类似青客公寓类型的房租中介。

UML模型

【设计模式二十一之中介者模式】中介者模式详解_第1张图片
如上述的UML图示所示,在中介者模式中其实只有三种角色
1: Mediator 抽象的中介对象,定义了统一的接口,主要用于各个同事之间进行通信
2:Concrete Mediator 具体的中介者角色,通过协调各个同事之间的行为,因此其必须依赖于各个同事角色
3:Colleague 同事角色,每一个同事角色都知道中介者,而且所有的同事之间的通信其实都必须要依赖于中介者,因此每个同事的行为主要分为两种行为,一种是同事本身自己的行为,这种行为叫做自发行为(Self-Method),还有一种就是依赖中介者才能完成的行为,叫做依赖行为(Dep-Method)

基于UML的代码

定义一个抽象的Mediator抽象类

package src.com.zzf.designpattern.mediatorpattern.demo3;


/**
 * MVC 框架。大家都应该使用过Struts 吧,MVC 框架,其中的C(Controller)就是一个中介者,叫做前
端控制器(Front Controller),它的作用就是把M(Model,业务逻辑)和V(View,视图)隔离开,协调M
和V 协同工作,把M 运行的结果和V 代表的视图融合成一个前端可以展示的页面,减少M 和V 的依赖关系。
MVC 框架已经成为一个非常流行、成熟的开发框架,这也是中介者模式优秀的一个体现
 * @author Administrator
 *
 */
public abstract class Mediator {
	//定义同事类
	protected ConcreteColleague1 c1;
	protected ConcreteColleague2 c2;
	
	
	//通过getter/setter方法把同事类注入进来
	public ConcreteColleague1 getC1() {
		return c1;
	}
	public void setC1(ConcreteColleague1 c1) {
		this.c1 = c1;
	}
	
	public ConcreteColleague2 getC2() {
		return c2;
	}
	public void setC2(ConcreteColleague2 c2) {
		this.c2 = c2;
	}
	
	//中介者模式的业务逻辑
	public abstract void doSomething1();
	
	public abstract void doSomething2();
}

定义具体的中介者,主要是定义中介通过中介者可以干嘛

package src.com.zzf.designpattern.mediatorpattern.demo3;


public class ConcreteMediator extends Mediator{

	@Override
	public void doSomething1() {
		// TODO Auto-generated method stub
		//调用同事类的方法,只要是public方法都可以调用
		super.c1.selfMethod1();
		super.c2.selfMethod2();
	}

	@Override
	public void doSomething2() {
		// TODO Auto-generated method stub
		super.c1.selfMethod1();
		super.c2.selfMethod2();
	}

}

定义抽象的同事类 ,每个同事类都必须要经过中介才能通信

package src.com.zzf.designpattern.mediatorpattern.demo3;


public abstract class Colleague {
	protected Mediator mediator;
	public Colleague(Mediator _mediator){
		this.mediator = _mediator;
	}
}

定义具体的同事类1

package src.com.zzf.designpattern.mediatorpattern.demo3;


public class ConcreteColleague1 extends Colleague{

	public ConcreteColleague1(Mediator _mediator) {
		super(_mediator);
		_mediator.setC1(this);
		// TODO Auto-generated constructor stub
	}
	
	//自有方法 self-method
	public void selfMethod1(){
		//处理自己的业务逻辑
		System.out.println("ConcreteColleague1 selfMethod1");
	}
	
	//依赖方法 dep-method
	public void depMethod1(){
		//处理自己的业务逻辑
		//自己不能处理的业务逻辑,委托给中介者处理
		super.mediator.doSomething1();
	}
}

定义同事类2

package src.com.zzf.designpattern.mediatorpattern.demo3;


public class ConcreteColleague2 extends Colleague{

	public ConcreteColleague2(Mediator _mediator) {
		super(_mediator);
		// TODO Auto-generated constructor stub
		_mediator.setC2(this);
	}
	
	//自有方法 self-method
	public void selfMethod2(){
		//处理自己的业务逻辑
		System.out.println("ConcreteColleague2 selfMethod2");
	}
	
	//依赖方法 dep-method
	public void depMethod2(){
	//处理自己的业务逻辑
	//自己不能处理的业务逻辑,委托给中介者处理
		super.mediator.doSomething2();
	}
}

测试部分的代码

package src.com.zzf.designpattern.mediatorpattern.demo3;

/**
 * 
 * @author Administrator
 *从类图中看,中介者模式有以下几部分组成:
	抽象中介者(Mediator)角色:抽象中介者角色定义统一的接口用于各同事角色之间的通信。
	具体中介者(Concrete Mediator)角色:具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。
	同事(Colleague)角色:每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。每个同事类的行为分为两种:
	一种是同事本身的行为,比如改变对象本身的状态,处理自己的行为等等,这种方法叫做自发行为(Self-Method),与其他的同事类或中介者没有任何的依赖;
	第二种是是必须依赖中介者才能完成的行为,叫做依赖方法(Dep-Method)。
 */
public class MediaTorMain {
	public static void main(String[] args) {
		Mediator mediator = new ConcreteMediator();
		ConcreteColleague1 colleague = new ConcreteColleague1(mediator);
		ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator);
		
		colleague.depMethod1();
		colleague2.depMethod2();
	}
}

场景一

场景

设计模式之禅中的案例,主要是采购,销售,库房管理人员的三者之间的关系,采购需要根据销售的情况以及库房管理剩余信息进行采购,库房需要根据销售情况,以及自身情况确定是否清理库存或者通知采购,销售又需要根据库房的情况和采购的情况决定是否需要促销活动等等,三者之间都是一种强关联的,如果让三者之间两两进行通信的话,这个时候就是网状结构,业务相对来说极其复杂,但是如果此时加入中介者,类似增加一个管理系统,那么采购,销售,库房管理人员其实是不需要直接联系的,只要查看这个管理系统,查看彼此的信息,就可以直接进行相应的变化,那么这个管理系统其实也就是充当着一个中介的角色

代码

package src.com.zzf.designpattern.mediatorpattern.demo2;


public abstract class AbstractMediator {
	Purchase mPurchase = null;
	Sale mSale = null;
	Stock mStock;
	
	public AbstractMediator() {
		// TODO Auto-generated constructor stub
		mPurchase = new Purchase(this);
		mSale = new Sale(this);
		mStock = new Stock(this);
	}
	
	/**
	 * 中介者模式需要做的事情
	 * @param str
	 * @param mobjects
	 */
	public abstract void execute(String str,Object ...mobjects); 
	
}

package src.com.zzf.designpattern.mediatorpattern.demo2;


public class Mediator extends AbstractMediator {

	@Override
	public void execute(String str, Object... mobjects) {
		// TODO Auto-generated method stub
		if (str.equals("purchase.buy")) { // 采购电脑
			this.buyComputer((Integer) mobjects[0]);
		} else if (str.equals("sale.sell")) { // 销售电脑
			this.sellComputer((Integer) mobjects[0]);
		} else if (str.equals("sale.offsell")) { // 折价销售
			this.offSell();
		} else if (str.equals("stock.clear")) { // 清仓处理
			this.clearStock();
		}
	}
	
	
	private void buyComputer(int number){
		System.out.println("buyComputer:"+number);
	}
	
	private void sellComputer(int number){
		System.out.println("sellComputer:"+number);
	}
	
	private void offSell(){
		System.out.println("offSell");
	}
	
	private void clearStock(){
		System.out.println("clearStock");
	}
}

package src.com.zzf.designpattern.mediatorpattern.demo2;


public abstract class AbstractColleague {
	AbstractMediator mediator;
	public AbstractColleague(AbstractMediator _meAbstractMediator) {
		// TODO Auto-generated constructor stub
		mediator = _meAbstractMediator;
	}
}

package src.com.zzf.designpattern.mediatorpattern.demo2;


public class Purchase extends AbstractColleague{

	public Purchase(AbstractMediator _meAbstractMediator) {
		super(_meAbstractMediator);
		// TODO Auto-generated constructor stub
	}
	
	//采购IBM型号的电脑
	public void buyIBMcomputer(int number){
		super.mediator.execute("purchase.buy", number);
	}
	
	//不在采购IBM电脑
	public void refuseBuyIBM(){
		System.out.println("不再采购IBM电脑");
	}

}

package src.com.zzf.designpattern.mediatorpattern.demo2;


import java.util.Random;

public class Sale extends AbstractColleague{

	public Sale(AbstractMediator _meAbstractMediator) {
		super(_meAbstractMediator);
		// TODO Auto-generated constructor stub
	}
	//销售IBM型号的电脑
	public void sellIBMComputer(int number){
		super.mediator.execute("sale.sell", number);
		System.out.println("销售IBM电脑"+number+"台");
	}
	
	//反馈销售情况,0——100之间变化,0代表根本就没人卖,100代表非常畅销,出1一个卖一个
	public int getSaleStatus(){
		Random rand = new Random(System.currentTimeMillis());
		int saleStatus = rand.nextInt(100);
		System.out.println("IBM电脑的销售情况为:"+saleStatus);
		return saleStatus;
	}
	
	//折价处理
	public void offSale(){
		super.mediator.execute("sale.offsell");
	}
	
}

package src.com.zzf.designpattern.mediatorpattern.demo2;


public class Stock extends AbstractColleague{
	
	//刚开始有100台电脑
	private static int COMPUTER_NUMBER =100;
	
	public Stock(AbstractMediator _meAbstractMediator) {
		super(_meAbstractMediator);
		// TODO Auto-generated constructor stub
	}

	//库存增加
	public void increase(int number){
		COMPUTER_NUMBER = COMPUTER_NUMBER + number;
		System.out.println("库存数量为:"+COMPUTER_NUMBER);
	}
	
	//库存降低
	public void decrease(int number){
		COMPUTER_NUMBER = COMPUTER_NUMBER - number;
		System.out.println("库存数量为:"+COMPUTER_NUMBER);
	}
	
	//获得库存数量
	public int getStockNumber(){
		return COMPUTER_NUMBER;
	}
	
	//存货压力大了,就要通知采购人员不要采购,销售人员要尽快销售
	public void clearStock(){
		System.out.println("清理存货数量为:"+COMPUTER_NUMBER);
		super.mediator.execute("stock.clear");
	}
}

package src.com.zzf.designpattern.mediatorpattern.demo2;


/**
 * 中介者模式:网关模式或者网络
 * @author Administrator
 *	Purchase ---->采购者
 *	Sale----->销售人员	
 *	Stock---->仓库管理人员
 *
 *
 *“每个类只和朋友类交流”,这个朋友类可不是越多越好,越多耦合性越大,改一个对象而要修改一片对象,这可不是面向对象设计所期望的
 *
 *
 *
 *从类图中看,中介者模式有以下几部分组成:
抽象中介者(Mediator)角色:抽象中介者角色定义统一的接口用于各同事角色之间的通信。
具体中介者(Concrete Mediator)角色:具体中介者角色通过协调各同事角色实现协作行为,因此它
必须依赖于各个同事角色。
同事(Colleague)角色:每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一
定要通过中介者角色协作。每个同事类的行为分为两种:一种是同事本身的行为,比如改变对象本身的状
态,处理自己的行为等等,这种方法叫做自发行为(Self-Method),与其他的同事类或中介者没有任何的依
赖;第二种是是必须依赖中介者才能完成的行为,叫做依赖方法(Dep-Method)。
 */
public class Test {
	public static void main(String[] args) {
		AbstractMediator mediator = new Mediator();  //定义一个中介者
		//采购人员采购电脑
		System.out.println("------采购人员采购电脑--------");
		Purchase purchase = new Purchase(mediator);
		purchase.buyIBMcomputer(100);
		//销售人员销售电脑
		System.out.println("\n------销售人员销售电脑--------");
		Sale sale = new Sale(mediator);
		sale.sellIBMComputer(1);
		//库房管理人员管理库存
		System.out.println("\n------库房管理人员清库处理--------");
		Stock stock = new Stock(mediator);
		stock.clearStock();
	}
}

场景二

场景

想一想,如果要做一个类似聊天室一样的软件,在某一个聊天室里面,首先你要加入聊天室,然后你可以群聊,当然你也可以单独给某一个人发,你所有的行为其实都是在聊天室下所做,那么这个时候,是不是可以认为这个聊天室就是你和所有对象进行交流的中介,你必须进入这个聊天室,然后才能够聊天,这个其实也是中介者模式的一个简单的应用。

代码

package src.com.zzf.designpattern.mediatorpattern.demo4;

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

public abstract class AsbChatMediator {
		//所有在聊天室里的人存这
	 	List list = new ArrayList<>();
	 	//群发
	    abstract void sendToAll(String msg);
	    //给某个人发送消息
	    abstract void senToPerson(String msg, String name);
	    //用户加入聊天室
	    abstract void join(UserColleague user);
    	//用户离开聊天室
	    abstract void leave(UserColleague user);

}

package src.com.zzf.designpattern.mediatorpattern.demo4;

public abstract class UserColleague {
	AsbChatMediator mediator = null;
    String name;
    //在创建对象的时候就把他的中间者传入,他要发送都是通过这个中介者来做的。
    public UserColleague(String name, AsbChatMediator mediator){
        this.name = name;
        this.mediator = mediator;
    }
    abstract void sendToAll(String msg);//给所有人发消息

    abstract void senToPerson(String msg, String name);//给某个人发送消息

    abstract void accept(String msg);//接受消息

    abstract void join();//加入聊天室

    abstract void leave();//离开聊天室

}

package src.com.zzf.designpattern.mediatorpattern.demo4;

public class ChatMediator extends AsbChatMediator{

	@Override
	void sendToAll(String msg) {
		// TODO Auto-generated method stub
		for(UserColleague userColleague:list){
			userColleague.accept(msg);
		}
	}

	@Override
	void senToPerson(String msg, String name) {
		// TODO Auto-generated method stub
		for(UserColleague userColleague:list){
			if (userColleague.name.equals(name)) {
				userColleague.accept(msg);
			}
		}
	}

	@Override
	void join(UserColleague user) {
		// TODO Auto-generated method stub
		list.add(user);
	}

	@Override
	void leave(UserColleague user) {
		// TODO Auto-generated method stub
		list.remove(user);
	}

}

package src.com.zzf.designpattern.mediatorpattern.demo4;

public class ConcreteCollegue extends UserColleague{

	public ConcreteCollegue(String name, AsbChatMediator mediator) {
		super(name, mediator);
		// TODO Auto-generated constructor stub
	}

	@Override
	void sendToAll(String msg) {
		// TODO Auto-generated method stub
		mediator.sendToAll(msg);
	}

	@Override
	void senToPerson(String msg, String name) {
		// TODO Auto-generated method stub
		mediator.senToPerson(msg, name);
	}

	@Override
	void accept(String msg) {
		// TODO Auto-generated method stub
		  System.out.println(this.name + "收到消息:" + msg );
	}

	@Override
	void join() {
		// TODO Auto-generated method stub
		mediator.join(this);
	}

	@Override
	void leave() {
		// TODO Auto-generated method stub
		mediator.leave(this);
	}

}

package src.com.zzf.designpattern.mediatorpattern.demo4;

public class ClientTest {
	public static void main(String[] args) {
		AsbChatMediator chatPlatform = new ChatMediator();
        ConcreteCollegue a = new ConcreteCollegue("张三", chatPlatform);
        ConcreteCollegue b = new ConcreteCollegue("李四", chatPlatform);
        ConcreteCollegue c = new ConcreteCollegue("王五", chatPlatform);
        a.join();
        b.join();
        c.join();
        System.out.println("-----------------张三群发送消息------------------");
        a.sendToAll("张三:大家听得到吗?");
        System.out.println("-----------------张三给李四私发消息------------------");
        a.senToPerson("张三:李四,我只想和你说", "李四");
        System.out.println("-----------------李四给王五私发消息------------------");
        b.senToPerson("李四:可以,请说", "王五");
        System.out.println("-----------------张三离开聊天室------------------");
        a.leave();


        System.out.println("-----------------李四群发送消息------------------");
        b.sendToAll("李四:张三能听到吗");
        
	}
}

本案例参考https://blog.csdn.net/niunai112/article/details/79913833

中介者模式应用和注意事项

中介者模式的优点其实很明显,每一个需要操作的对象类其实是不需要与其他的对象类进行直接交互的,降低了他们之间的相互耦合性。只保证和一个中介打交道就可以了。
但是缺点其实也很明显,就是当具体的同事类过多的时候,就会让中介者类过于的庞大,逻辑复杂。
使用场景:
当对象与对象之间的逻辑关系类似网状的时候,这个时候可以考虑使用中介者模式,这样可以让其以类似星性拓扑型结构进行逻辑梳理,中介者模式相对来说比较容易理解,但是使用的时候还是要考虑到相应的适用场景




欢迎继续访问,我的博客

你可能感兴趣的:(Java设计模式学习,java设计模式)