模式定义
中介者模式(Mediator Pattern)定义:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
UML类图
- 抽象中介者 Mediator
- 具体中介者 ConcreteMediator
- 抽象同事类 Colleague
具体同事类 ConcreteColleague
代码结构
public static class MediatorApp { public static void Run() { ConcreteMediator m = new ConcreteMediator(); ConcreteColleague1 c1 = new ConcreteColleague1(m); ConcreteColleague2 c2 = new ConcreteColleague2(m); m.Colleague1 = c1; m.Colleague2 = c2; c1.Send("How are you?"); c2.Send("Fine,thanks"); Console.ReadKey(); } } /// <summary> /// 抽象中介者 /// </summary> abstract class Mediator { public abstract void Send(string message, Colleague colleague); } /// <summary> /// 具体中介者(管理相互交换的两个‘同事’类) /// </summary> class ConcreteMediator : Mediator { private ConcreteColleague1 _colleague1; private ConcreteColleague2 _colleague2; public ConcreteColleague1 Colleague1 { set { _colleague1 = value; } } public ConcreteColleague2 Colleague2 { set { _colleague2 = value; } } public override void Send(string message, Colleague colleague) { if(colleague == _colleague1) { _colleague2.Notify(message); } else { _colleague1.Notify(message); } } } /// <summary> /// 抽象同事类,关联抽象中介者,两个“同事”的通信通过中介者 /// </summary> abstract class Colleague { protected Mediator mediator; public Colleague(Mediator mediator) { this.mediator = mediator; } } /// <summary> /// 具体中介者 /// </summary> class ConcreteColleague1 : Colleague { public ConcreteColleague1(Mediator mediator) : base(mediator) { } public void Send(string message) { mediator.Send(message, this); } public void Notify(string message) { Console.WriteLine("Colleague1 gets message:"+message); } } /// <summary> /// 具体中介者 /// </summary> class ConcreteColleague2 : Colleague { public ConcreteColleague2(Mediator mediator) : base(mediator) { } public void Send(string message) { mediator.Send(message, this); } public void Notify(string message) { Console.WriteLine("Colleague2 gets message:" + message); } }
情景案例
这里实现个简单的小游戏,游戏有电脑和人两个角色,不同角色间相互攻击,参与者存在一定的概率被杀死,当每个参与者死亡通知活着的参与者。
public static class RealWorldMediatorApp { public static void Run() { Game game = new Game(); Computer com1 = new Computer(game, "Computer1"); Computer com2 = new Computer(game, "Computer2"); Person per1 = new Person(game, "Person1"); Person per2 = new Person(game, "Person2"); game.Register(com1); game.Register(com2); game.Register(per1); game.Register(per2); for (int i = 0; i < 10; i++) { com1.Attack("Person1"); per2.Attack("Computer2"); com2.Attack("Person2"); per1.Attack("Computer1"); } Console.ReadKey(); } } /// <summary> /// 抽象中介者 /// </summary> abstract class AbstractGame { public abstract void Register(Member member); public abstract void Attack(Member attacker, string attackee); public abstract void Notify(Member member); } /// <summary> /// 具体中介者(管理相互交换的两个‘同事’类) /// </summary> class Game : AbstractGame { private Dictionary<string, Member> _computerLst = new Dictionary<string, Member>(); private Dictionary<string, Member> _personLst = new Dictionary<string, Member>(); public override void Attack(Member attacker, string attackee) { Member attackeeMember; if (attacker.GetType() == typeof(Computer)) { attackeeMember = _personLst[attackee]; } else { attackeeMember = _computerLst[attackee]; } attackeeMember.Hurt(); } public override void Notify(Member member) { foreach (var item in _personLst) { if (item.Value.IsLive) { string msg = member.Name + " is dead"; item.Value.ReceiveNotify(msg); } } foreach (var item in _computerLst) { if (item.Value.IsLive) { string msg = member.Name + " is dead"; item.Value.ReceiveNotify(msg); } } } public override void Register(Member member) { if (member.GetType() == typeof(Computer)) { _computerLst.Add(member.Name, member); } else { _personLst.Add(member.Name, member); } } } /// <summary> /// 抽象同事类,关联抽象中介者,两个“同事”的通信通过中介者 /// </summary> abstract class Member { public bool IsLive { get; private set; } private string _name = string.Empty; public string Name { get { return _name; } } protected AbstractGame mediator; public Member(AbstractGame mediator, string name) { this.mediator = mediator; this._name = name; this.IsLive = true; } public void Attack(string attackee) { if (this.IsLive) { mediator.Attack(this, attackee); } } public void Hurt() { Random rd = new Random(); int ranNum = rd.Next(0, 2); if (this.IsLive && ranNum == 1) { this.IsLive = false; mediator.Notify(this); } } public void ReceiveNotify(string msg) { string strMsg = this.Name + " Receive :" + msg; Console.WriteLine(strMsg); } } /// <summary> /// 电脑角色 /// </summary> class Computer : Member { public Computer(AbstractGame mediator, string name) : base(mediator, name) { } } /// <summary> /// 人员角色 /// </summary> class Person : Member { public Person(AbstractGame mediator, string name) : base(mediator, name) { } }