前置文章: 用心理解设计模式——设计模式的原则
设计模式相关代码已统一放至 我的 Github
一、定义
行为型模式之一。
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to referring to each other explicitly, and it lets you vary their interaction independently.
(定义一个对象,用于封装一组对象的交互。中介者通过防止对象显式地引用彼此,来提升耦合松散度,并且允许你独立地更改它们之间的交互。)
二、结构解析
中介者模式的一般结构有四种角色:抽象同事、真实同事、抽象中介者、具体中介者。
抽象同事,负责定义和持有抽象类型中介者,可定义一个方法,声明 “中介者和同事将在此方法中与进行交互”。
具体同事,确定具体中介者,当好螺丝钉,只做自己应做的事。根据自己需要的输入资源,产出自己应产出的产品。
抽象中介者,负责为每个具体同事提供需要什么资源和产出什么产品的接口方法。可为客户端定义一个获得最终产品的接口。
具体中介者,实现抽象中介者定义的接口方法,负责具体协调逻辑,确定每个具体同事所需资源的组成,确定每个具体同事的产出去向,决定最终产品的组成。
三、评价
中介者模式,作为行为型模式之一,它将 “中介/协调/调停” 这个抽象概念抽象为类。并定义了多个同事(有上下游资源依赖、协作等关系)之间一起工作、交互时,由 “中介” 进行协调的行为过程。让具体同事之间的耦合得以解除,每个具体同事都只与中介者进行交互,然后各司其职。它把同事间的多对多的网状交互,变成一对多,“一”指中介者。
新增具体同事较方便,同时,需要修改抽象中介者,修改或新增具体中介者。
四、实现
using System.Collections.Generic;
namespace Mediator
{
//辅助测试参数类
public class ARes { }
public class AProduct { }
public class BRes { }
public class BProduct { }
public class CRes { }
public class CProduct { }
public class FinalProduct { }
//抽象中介者类
public abstract class Mediator
{
//对具体同事A提供的接口,需要什么、产出什么
public abstract ARes GetARes();
public abstract void OutputAProduct(AProduct aProduct);
//对具体同事A提供的接口,需要什么、产出什么
public abstract BRes GetBRes();
public abstract void OutputBProduct(BProduct bProduct);
//对具体同事A提供的接口,需要什么、产出什么
public abstract CRes GetCRes();
public abstract void OutputCProduct(CProduct cProduct);
public abstract FinalProduct GetFinalProduct();
}
//抽象同事类
public abstract class Colleague
{
//持有中介者,只和中介者交互
protected Mediator mediator;
public Colleague(Mediator mediator)
{
this.mediator = mediator;
}
//抽象接口,做自己的事,在这个方法中,从中介者拿到所需资源,生产,然后将产品交给中介者。
public abstract void DoSelfDuty();
}
//具体同事A
public class ConcreteColleagueA : Colleague
{
//构造函数,至少需要传入中介者
public ConcreteColleagueA(Mediator mediator) : base(mediator) { }
public override void DoSelfDuty()
{
//从中介者拿到所需资源
ARes aRes = this.mediator.GetARes();
//生产
AProduct aProduct = ProcessA(aRes);
//将产品交给中介者
this.mediator.OutputAProduct(aProduct);
}
private AProduct ProcessA(ARes aRes)
{
//这里简略了资源变为产品的加工过程
return new AProduct();
}
}
//具体同事B
public class ConcreteColleagueB : Colleague
{
public ConcreteColleagueB(Mediator mediator) : base(mediator) { }
public override void DoSelfDuty()
{
BRes bRes = this.mediator.GetBRes();
BProduct bProduct = ProcessB(bRes);
this.mediator.OutputBProduct(bProduct);
}
private BProduct ProcessB(BRes bRes)
{
return new BProduct();
}
}
//具体同事C
public class ConcreteColleagueC : Colleague
{
public ConcreteColleagueC(Mediator mediator) : base(mediator) { }
public override void DoSelfDuty()
{
CRes cRes = this.mediator.GetCRes();
CProduct cProduct = ProcessC(cRes);
this.mediator.OutputCProduct(cProduct);
}
private CProduct ProcessC(CRes cRes)
{
return new CProduct();
}
}
//具体中介者类, 负责具体协调逻辑。
public class ConcreteMediator : Mediator
{
//示例,产品或半成品仓库,缓存具体同事ABC的产出。ABC所需的资源也可从这里拿,最终产品所需的资源也可以从这里拿。
protected List<AProduct> aProductList = new List<AProduct>();
protected List<BProduct> bProductList = new List<BProduct>();
protected List<CProduct> cProductList = new List<CProduct>();
public override ARes GetARes()
{
//这里简略ARes的产生过程,这里可以决定A所需的资源由什么组成
return new ARes();
}
public override BRes GetBRes()
{
//这里简略BRes的产生过程,这里可以决定B所需的资源由什么组成
return new BRes();
}
public override CRes GetCRes()
{
//这里简略CRes的产生过程,这里可以决定C所需的资源由什么组成
return new CRes();
//例如: CRes可能由AProduct和BProduct两种半成品组成, 需要同时在CRes中提供对应的构造函数
//return new CRes(aProductSet[0], bProductSet[0]);
}
//A产出的产品放入缓存仓库
public override void OutputAProduct(AProduct aProduct)
{
aProductList.Add(aProduct);
}
//B产出的产品放入缓存仓库
public override void OutputBProduct(BProduct bProduct)
{
bProductList.Add(bProduct);
}
//C产出的产品放入缓存仓库
public override void OutputCProduct(CProduct cProduct)
{
cProductList.Add(cProduct);
}
//最终产品,提供给客户端的接口
public override FinalProduct GetFinalProduct()
{
//这里简略FinalProduct的产生过程。
//这里可以决定最终产品所需的资源由什么组成。
//可能ABC其中的某个产品就是最终产品,也可能由ABC的半成品组成,但是这个组成过程也可以扩展一个D并且放到D中去。最终让某个具体同事类的产品作为最终产品。
return new FinalProduct();
}
}
public class Client
{
static public void Main()
{
//构建具体类
ConcreteMediator concreteMediator = new ConcreteMediator();
ConcreteColleagueA concreteColleagueA = new ConcreteColleagueA(concreteMediator);
ConcreteColleagueB concreteColleagueB = new ConcreteColleagueB(concreteMediator);
ConcreteColleagueC concreteColleagueC = new ConcreteColleagueC(concreteMediator);
//各司其职
concreteColleagueA.DoSelfDuty();
concreteColleagueB.DoSelfDuty();
concreteColleagueC.DoSelfDuty();
//得到最终产品
FinalProduct finalProduct = concreteMediator.GetFinalProduct();
}
}
}