设计模式 之 中介者

时间:2021-12-22 21:58:42

中介者模式(Mediator)

          用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。




       腾讯QQ(简称“QQ”)是腾讯公司开发的一款基于Internet的即时通信(IM)软件。标志是一只戴着红色围巾的小企鹅。QQ注册用户由1999年的2人(马化腾和张志东)到现在已经发展到上亿用户,2014年4月11日21点11分在线人数突破两亿,如今已成为腾讯公司的代表之作,是中国目前使用最广泛的交流软件。


       我们都知道用QQ能够点对点地跟别人聊天,也能在讨论组或者QQ群里面一人一句的聊天,如果点对点的聊天是每个人即作为服务器也作为客户端,发送消息和接收消息的话。那多人聊天采用这种结构就会相当的复杂,那我们该怎么办呢?加入一个中介者角色,充当通信服务器,每个人都作为客户端与服务器通信。下面我们就来看看具体实现:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;

namespace Mediator
{
    //用户接口
    public interface IUser
    {
        //接收消息
        void receiveMessage(String message);
        //发送消息
        void sendMessage(String message);
        //获得发送的消息内容
        string getMessage();
    }

    //中介者接口
    public interface IMediator
    {
        //注册用户信息
        void regist(IUser user);
        //发送消息给所有人
        void notifyAllMessage(IUser user);

    }
    public class ConcreteMediator : IMediator
    {
        private IList<IUser> list = new List<IUser>();

        public void regist(IUser user)
        {
            if (user!=null && !list.Contains(user)){
                list.Add(user);
            }
        }
        public void notifyAllMessage(IUser user)
        {
            for (int i = 0; i < list.Count; i++)
            {
                if (!list[i].Equals (user))
                {
                    list[i].receiveMessage(user.getMessage());
                    
                }
            }
        }
    }

    //抽象用户信息
    public abstract class AbstractUser : IUser
    {
        protected IMediator mediator;
        protected String name;
        protected String message;

        public AbstractUser(IMediator mediator, string name)
        {
            this.mediator = mediator;
            this.name = name;
        }
        public void sendMessage(String message)
        {
            this.message = message;
            Console.WriteLine(this.name + " 说:" + this.message);
            mediator.notifyAllMessage(this);
        }
        public abstract void receiveMessage(string message);
        
        public string getMessage()
        {
            return message;
        }
    }
    //用户A
    public class UserA : AbstractUser
    {
        public UserA(IMediator mediator, string name)
            : base(mediator, name)
        {
            mediator.regist(this);
        }

        public override void receiveMessage(string message)
        {
            Console.WriteLine("User A Received Message :" + message);
        }
    }
    //用户B
    public class UserB : AbstractUser
    {
        public UserB(IMediator mediator, string name)
            : base(mediator, name)
        {
            mediator.regist(this);
        }

        public override void receiveMessage(string message)
        {
            Console.WriteLine("User B Received Message :" + message);
        }
    }
    //用户C
    public class UserC : AbstractUser
    {
        public UserC(IMediator mediator, string name)
            : base(mediator, name)
        {
            mediator.regist(this);
        }

        public override void receiveMessage(string message)
        {
            Console.WriteLine("User C Received Message :" + message);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            //创建聊天室(中介者)
            IMediator mediator = new ConcreteMediator();
            //创建用户信息
            IUser userA = new UserA(mediator, "张三");
            IUser userB = new UserB(mediator, "李四");
            IUser userC = new UserC(mediator, "王五");

            Console.WriteLine("------------------------------------------------------");
            userA.sendMessage("大家好,我叫张三!初来乍到,请多多关照!");
            Console.WriteLine();
            Console.WriteLine("------------------------------------------------------");
            userB.sendMessage("大家好,我叫李四!欢迎加入!");
            Console.WriteLine();
            Console.WriteLine("------------------------------------------------------");
            userC.sendMessage("我是王五,欢迎欢迎!");
            Console.WriteLine();
            Console.WriteLine("------------------------------------------------------");
        }
    }
}

设计模式 之 中介者

类图:

                                       设计模式 之 中介者

中介者模式包含如下几个角色:
    Mediator(抽象中介者):它定义一个接口,该接口用于与各同事对象之间进行通信。
    ConcreteMediator(具体中介者):具体中介者角色实现抽象中介者接口,具体协调各个同事类之间的协作。
    Colleague(抽象同事类):定义与中介者之间沟通的接口。
    ConcreteColleague(具体同事类):实现抽象同事角色接口,具体处理与中介者的通信行为。


主要优点:

    1.中介者模式简化了对象之间的交互。一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构转换成相对简单的星型结构。
    2.中介者模式可将各同事对象解耦。


主要缺点:

      在具体中介者类中包含了大量同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。


适用场景:

    1.一组对象以定义良好但是复杂的方式进行通信,产生的相互依赖关系结构混乱且难以理解。注意是多个对象之前相互依赖。
    2.想定制一个分部在多个类中的行为,而不像生成太多的子类的场合。


相关模式:

    1.外观:在外观中,外观角色是构成系统内部复杂子系统的单一窗口,对系统外部提供更高一级的接口。外观是单向的信息传达。
    2.中介者:中介者角色充当着各个同事对象之间信息交互的中间角色。中介者是双向的信息通信。