C#设计模式(16)——中介者模式

出处:https://www.cnblogs.com/wyy1234/html

 

阅读目录网络

 


1.中介者模式介绍

  中介者模式,定义了一个中介对象来封装一系列对象之间的交互关系,中介者使各个对象之间不须要显式地相互引用,从而下降耦合性。在开发中咱们会遇到各个对象相互引用的状况,每一个对象均可以和多个对象进行交互,这时将会造成复杂的一对多结构的网状结构,各个对象之间过分耦合,这样不利于类的复用和扩展。若是引入了中介者模式,各个对象都经过中介者进行交互,那么对象之间的关系将变成一对一的星型结构。ide

 

  咱们采用园友LearningHard玩牌的例子来理解中介者模式的用法。在现实生活中,两我的打牌,若是某我的赢了会影响到对方的状态。标准中介者模式有抽象中介者角色,具体中介者角色、抽象同事类和具体同事类四个角色,其中打牌的人都是具体的同事类的对象,算帐的平台是中介者对象。若是此时不采用中介者模式实现的话,则代码实现打牌的场景以下所示:this

复制代码
//抽象玩家类
    public abstract class AbstractCardPlayer
    {
        public int MoneyCount { get; set; }
        public AbstractCardPlayer()
        {
            this.MoneyCount = 0;
        }
        public abstract void ChangeCount(int count, AbstractCardPlayer other);
    }
//玩家A类 public class PlayerA : AbstractCardPlayer { public override void ChangeCount(int count, AbstractCardPlayer other) { this.MoneyCount += count; other.MoneyCount -= count; } }
//玩家B类 public class PlayerB : AbstractCardPlayer { public override void ChangeCount(int count, AbstractCardPlayer other) { this.MoneyCount += count; other.MoneyCount -= count; } }

class Program { static void Main(string[] args) { AbstractCardPlayer a = new PlayerA() { MoneyCount = 20 }; AbstractCardPlayer b = new PlayerB() { MoneyCount = 20 }; //玩家a赢了玩家b 5元 Console.WriteLine("a赢了b5元"); a.ChangeCount(5, b); Console.WriteLine($"玩家a如今有{a.MoneyCount}元"); Console.WriteLine($"玩家b如今有{b.MoneyCount}元"); //玩家b赢了玩家a 10元 Console.WriteLine("b赢了a10元"); b.ChangeCount(10, a); Console.WriteLine($"玩家a如今有{a.MoneyCount}元"); Console.WriteLine($"玩家b如今有{b.MoneyCount}元"); Console.ReadKey(); } }
复制代码

运行结果以下:spa

  上边的代码知足了玩牌的功能,可是有一些缺陷:咱们看到上边栗子中算钱的功能是交给赢家的a.ChangeCount(count, b)方法来实现的,这时是赢家找输家要钱 赢家a和输家b是直接通讯的。当玩家比较多的时候,例如a赢了,bcde四个玩家都会输5元,那么a就要和bcde玩家都要通讯(多玩家方法改为:a.ChangeCount(count,b,c,d,e)),如b赢了同理,各个玩家组成了一个复杂的通讯网络,就像上边的网状图,各个玩家过分耦合。若是咱们引入一个中间人来负责统一结算,赢家就能够直接找中间人结算,没必要直接找全部的输家要帐了,代码以下:code

复制代码
//抽象玩家类
    public abstract class AbstractCardPlayer
    {
        public int MoneyCount { get; set; }
        public AbstractCardPlayer()
        {
            this.MoneyCount = 0;
        }
        public abstract void ChangeCount(int count, AbstractMediator mediator);
    }
    //玩家A类
    public class PlayerA : AbstractCardPlayer
    {
        //经过中介者来算帐,不用直接找输家了
        public override void ChangeCount(int count, AbstractMediator mediator)
        {
            mediator.AWin(count);
        }
    }
    //玩家B类
    public class PlayerB : AbstractCardPlayer
    {
        public override void ChangeCount(int count, AbstractMediator mediator)
        {
            mediator.BWin(count);
        }
    }
    //抽象中介者
    public abstract class AbstractMediator
    {
        //中介者必须知道全部同事
        public AbstractCardPlayer A;
        public AbstractCardPlayer B;
        public AbstractMediator(AbstractCardPlayer a,AbstractCardPlayer b)
        {
            A = a;
            B = b;
        }
        public abstract void AWin(int count);
        public abstract void BWin(int count);
    }
    //具体中介者
    public class Mediator : AbstractMediator
    {
        public Mediator(AbstractCardPlayer a,AbstractCardPlayer b):base(a,b){}
        public override void AWin(int count)
        {
            A.MoneyCount += count;
            B.MoneyCount -= count;
        }
        public override void BWin(int count)
        {
            A.MoneyCount -= count;
            B.MoneyCount += count;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            AbstractCardPlayer a = new PlayerA() { MoneyCount = 20 };
            AbstractCardPlayer b = new PlayerB() { MoneyCount = 20 };
            AbstractMediator mediator = new Mediator(a, b);
            //玩家a赢了玩家b 5元
            Console.WriteLine("a赢了b5元");
            a.ChangeCount(5, mediator);
            Console.WriteLine($"玩家a如今有{a.MoneyCount}元");
            Console.WriteLine($"玩家b如今有{b.MoneyCount}元");
            //玩家b赢了玩家a 10元
            Console.WriteLine("b赢了a10元");
            b.ChangeCount(10, mediator);
            Console.WriteLine($"玩家a如今有{a.MoneyCount}元");
            Console.WriteLine($"玩家b如今有{b.MoneyCount}元");
            Console.ReadKey();
        }
    }
复制代码

  运行结果和不用中介者的例子一致。咱们能够看到中介者模式下降了各个同事对象的耦合,同事类之间不用直接通讯,直接找中介者就好了,可是中介者模式并无下降业务的复杂度,中介者将同事类间的复杂交互逻辑从业务代码中转移到了中介者类的内部。标准中介者模式有抽象中介者角色,具体中介者角色、抽象同事类和具体同事类四个角色,在实际开发中有时候不必对具体中介者角色和具体用户角色进行抽象(如联合国做为一个中介者,负责调停各个国家纠纷,可是不必把单独的联合国抽象成一个抽象中介者类;上边例子的抽象玩家类和抽象中介者类都是不必的),咱们能够根据具体的状况来来选择是否使用抽象中介者和抽象用户角色。htm

2.小结

1.上边例子的类图对象

中介者模式优势:blog

  1 下降了同事类交互的复杂度,将一对多转化成了一对一;开发

  2 各个类之间的解耦;

  3 符合迪米特原则。

中介者模式缺点:

  1 业务复杂时中介者类会变得复杂难以维护。

 

参考文献

 [1] http://www.runoob.com/design-pattern/mediator-pattern.html

 [2] http://www.cnblogs.com/zhili/p/MediatorPattern.html

相关文章
相关标签/搜索