设计模式-中介者模式(Mediator)
定义
“定义一个接口用来封装一群对象的互动行为。中介者通过移除对象之间的引用,来减少它们之间的耦合度,并且能够改变它们之间的互动独立性。”
实现
类图
说明
Mediator(中介者接口)、ConcreteMediator(中介者接口实现类)
- 由Mediator定义让Colleague类操作的接口;
- ConcreteMediator 实现类中包含所有ConcreteColleague的对象的引用;
- ConcreteColleague类之间的互动会在ConcreteMediator中发生;
Colleague(同事接口)
- 拥有一个Mediator成员,通过它来调用中介者的功能;
ConcreteColleague_X(同事接口实现类)
- 实现Colleague的类,对于单一实现而言,只会依赖一个Mediator接口;
代码
以下代码在unity环境下编写运行
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ZhhDesignPattern
{
//中介者模式
public class Mediator_UnitTest : MonoBehaviour//测试程序
{
ConcreateMediator mediator;//中介者
Colleague_landlord_A landlord_A;//同事A(房东A)
Colleague_landlord_B landlord_B;//同事B(房东B)
Colleague_tenant tenant_C;//同事C(租客C)
void Awake()
{
//初始化
mediator = new ConcreateMediator();
landlord_A = new Colleague_landlord_A(mediator);
landlord_B = new Colleague_landlord_B(mediator);
tenant_C = new Colleague_tenant(mediator);
mediator.InitialAllColleague(landlord_A, landlord_B, tenant_C);
}
void Start()
{
landlord_A.Action();//房主A有出租需求
landlord_B.Action();//房主B有出租需求
tenant_C.Action();//房客C有租房需求
}
}
//中介者接口
public abstract class Mediator
{
//用于Colleague同事之间的交互信息,本例以房主和租客为例子,使用message传递房屋信息
public abstract void SendMessage(ColleagueTypeEnum type, Colleague theColleague, string message);
}
//同事接口
public abstract class Colleague
{
protected Mediator mediator = null;//中介者,通过mediator对外沟通
public Colleague(Mediator mediator)
{
this.mediator = mediator;
}
//通知请求,通过此函数传递请求
public abstract void Request(string message);
}
public class Colleague_landlord_A : Colleague//房东
{
public Colleague_landlord_A(Mediator mediator) : base(mediator)
{
}
//房东有出租房屋的需求
public void Action()
{
mediator.SendMessage(ColleagueTypeEnum.Landlord_A, this, "房东A有一个出租要求");
}
public override void Request(string message)
{
Debug.Log(GetHouseMsg());//当有租客有需求时提供信息
}
//获取房屋信息,以字符串返回房屋信息
public string GetHouseMsg()
{
return "房东A有一套房屋出租,地址a,价格b,套型c";
}
}
public class Colleague_landlord_B : Colleague//房东
{
public Colleague_landlord_B(Mediator mediator) : base(mediator)
{
}
//房东有出租房屋的需求
public void Action()
{
mediator.SendMessage(ColleagueTypeEnum.Landlord_B, this, "房东B有一个出租要求");
}
public override void Request(string message)
{
Debug.Log(GetHouseMsg());//当有租客有需求时提供信息
}
//获取房屋信息,以字符串返回房屋信息
public string GetHouseMsg()
{
return "房东B有一套房屋出租,地址d,价格e,套型f";
}
}
public class Colleague_tenant : Colleague//房客
{
public Colleague_tenant(Mediator mediator) : base(mediator)
{
}
//房客有租房的需求
public void Action()
{
mediator.SendMessage(ColleagueTypeEnum.Tenant_A, this, "租客C有租房需求");
}
public override void Request(string message)
{
Debug.Log(GetSelfMsg());
}
//获取租客自身信息,以字符串返回
public string GetSelfMsg()
{
return "房客C有一个租房需求,姓名,年龄,职业";
}
}
//中介者
public class ConcreateMediator : Mediator
{
//中介者需要知道所有的同事colleague(房主和房客)的信息
Colleague_landlord_A landlord_A = null;
Colleague_landlord_B landlord_B = null;
Colleague_tenant tenant_C = null;
//将所有引用添加到中介者中
public void InitialAllColleague(Colleague_landlord_A landlordA, Colleague_landlord_B landlordB, Colleague_tenant tenantC)
{
landlord_A = landlordA;
landlord_B = landlordB;
tenant_C = tenantC;
}
public override void SendMessage(ColleagueTypeEnum type, Colleague theColleague, string message)
{
switch (type)
{
case ColleagueTypeEnum.Landlord_A://当有租客时获取租客信息
tenant_C.Request(message);
break;
case ColleagueTypeEnum.Landlord_B:
tenant_C.Request(message);
break;
case ColleagueTypeEnum.Tenant_A://当租客有租房请求时获取所有房主房屋信息
landlord_A.Request(message);
landlord_B.Request(message);
break;
default:
break;
}
}
}
public enum ColleagueTypeEnum//同事类型,用于记录同事Colleague便于在实体中介者中区分使用
{
Tenant_A,
Landlord_A,
Landlord_B,
}
}
代码说明
- 每一个继承自Colleague的ConcreteColleague_X类,需要对外界沟通时,都会通过mediator来传递信息,而来自Mediator的请求也会通过父类的抽象方法Request()来进行通知;
- Mediator定义了一个抽象方法SendMessage(),主要用于从外界传递信息给Colleague;
- 具体实现的ConcreteMediator类,拥有所有要在内部进行沟通的Colleague子类的引用;
使用中介者模式的优点
- 不会引入太多其他的系统
- 系统被依赖的程度也降低
小结
作为系统间沟通的接口
中介者模式能让系统之间的耦合度降低,提升系统的可维护性;但身为模式中的中介者角色类,也会存在着接口过大的风险,此时需要配合其他模式来进行优化;