中介者模式(Mediator):
在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室、QQ群、短信平台和房产中介。不论是QQ游戏还是QQ群,它们都是充当一个中间平台,QQ用户可以登录这个中间平台与其他QQ用户进行交流,如果没有这些中间平台,我们如果想与朋友进行聊天的话,可能就需要当面才可以了。电话、短信也同样是一个中间平台,有了这个中间平台,每个用户都不要直接依赖与其他用户,只需要依赖这个中间平台就可以了,一切操作都由中间平台去分发。中介者模式,定义了一个中介对象来封装一系列对象之间的交互关系。中介者使各个对象之间不需要显式地相互引用,从而使耦合性降低,而且可以独立地改变它们之间的交互行为。
中介者模式的角色:
1)抽象中介者(Mediator):定义了同事对象到中介者对象的接口。
2)具体中介者(ConcreteMediator):实现抽象类的方法,它需要知道具体的同事类并从具体同事类接受消息,向具体同事对象发出命令。
3)抽象同事类(Colleague):定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
4)具体同事类(ConcreteColleague):每个具体同事类只知道自己的行为,而不了解其他同事类的情况,但它们认识中介者对象。
示例:
以现实生活中打牌为例,若不使用中介者模式。
1 /// <summary> 2 /// 抽象牌友类 3 /// </summary> 4 public abstract class AbstractCardPartner 5 { 6 public int Money { get; set; } 7 8 public abstract void ChangeMoney(int money, AbstractCardPartner other); 9 } 10 11 /// <summary> 12 /// 牌友A 13 /// </summary> 14 public class PartnerA : AbstractCardPartner 15 { 16 public override void ChangeMoney(int money, AbstractCardPartner other) 17 { 18 Money += money; 19 other.Money -= money; 20 } 21 } 22 23 /// <summary> 24 /// 牌友B 25 /// </summary> 26 public class PartnerB : AbstractCardPartner 27 { 28 public override void ChangeMoney(int money, AbstractCardPartner other) 29 { 30 Money += money; 31 other.Money -= money; 32 } 33 } 34 35 internal class Program 36 { 37 private static void Main(string[] args) 38 { 39 AbstractCardPartner A = new PartnerA(); 40 A.Money = 20; 41 AbstractCardPartner B = new PartnerB(); 42 B.Money = 20; 43 44 // A赢了B的钱减少 45 A.ChangeMoney(5, B); 46 Console.WriteLine("A 现在的钱是:{0}", A.Money); // 应该是25 47 Console.WriteLine("B 现在的钱是:{0}", B.Money); // 应该是15 48 49 // B赢了A的钱减少 50 B.ChangeMoney(10, A); 51 Console.WriteLine("A 现在的钱是:{0}", A.Money); // 应该是15 52 Console.WriteLine("B 现在的钱是:{0}", B.Money); // 应该是25 53 } 54 }
这样的实现确实解决了上面场景中的问题,并且使用了抽象类使具体牌友A和牌友B都依赖于抽象类,从而降低了同事类之间的耦合度。但是如果其中牌友A发生变化时,此时就会影响到牌友B的状态,如果涉及的对象变多的话,这时候某一个牌友的变化将会影响到其他所有相关联的牌友状态。例如牌友A算错了钱,这时候牌友A和牌友B的钱数都不正确了,如果是多个人打牌的话,影响的对象就会更多。这时候就会思考——能不能把算钱的任务交给程序或者算数好的人去计算呢,这时候就有了我们QQ游戏中的欢乐斗地主等牌类游戏了。
1 /// <summary> 2 /// 抽象牌友类 3 /// </summary> 4 public abstract class AbstractCardPartner 5 { 6 protected AbstractMediator mediator; 7 8 public int Money { get; set; } 9 10 public abstract void Change(int money, AbstractMediator mediator); 11 } 12 13 /// <summary> 14 /// 牌友A 15 /// </summary> 16 public class PartnerA : AbstractCardPartner 17 { 18 public PartnerA(int money) 19 { 20 Money = money; 21 } 22 23 public override void Change(int money, AbstractMediator mediator) 24 { 25 Console.WriteLine($"{nameof(PartnerA)}赢了"); 26 mediator.Change(money, this); 27 } 28 } 29 30 /// <summary> 31 /// 牌友B 32 /// </summary> 33 public class PartnerB : AbstractCardPartner 34 { 35 public PartnerB(int money) 36 { 37 Money = money; 38 } 39 40 public override void Change(int money, AbstractMediator mediator) 41 { 42 Console.WriteLine($"{nameof(PartnerB)}赢了"); 43 mediator.Change(money, this); 44 } 45 } 46 47 /// <summary> 48 /// 牌友B 49 /// </summary> 50 public class PartnerC : Ab