我们知道面向对象应用程序是由一组为了提供某种服务而彼此交互的对象组成。当彼此引用的对象数量比较少时,此时对象之间就为直接交互(点对点)。而当对象的数量增加时,这种直接交互会导致对象之间复杂的、混乱的引用,最后形成一张巨大的网,这就会影响应用程序的可维护性。同时,因为对象之间的高耦合,当一个对象直接引用其他的对象时,缩小了这些对象的复用范围。
    因此:我们可使用一个“中介对象”来管理对象间的关联关系,避免相互交互的对象之间的紧耦合引用关系,从而更好地抵御变化。
   以上的变化反映在下图:

   
   中介者模式的相关角色如下图:

由图可知,它的角色有:
 1、抽象同伴类角色 ColleagueBase。它是"具体同伴类角色"的基类,同时在它内部要引用到一个抽象中介类成员。
 2、抽象中介类角色 MediatorBase。它是"具体中介类角色"的基类. 它定义了要求其子类必须完成的方法,此方法可以被具体同伴类角色调用。
 3、具体同伴类角色 ConcreteColleague A/B. 它们都继承自"抽象同伴类角色 ColleagueBase",由具体同伴类角色所产生的实例化对象不再像以前那样相互之间直接联系,而是通过"具体中介类角色"进行统一协调和管理。在上图中所定义的Send和 Receive方法表示此类具有发送和接收信息的功能,但这时的发送和接收通讯是在ConcreteColleague 与Mediator之间进行,而不是在ConcreteColleague之间直接通讯,因为通过Mediator,它们与自己的同伴之间早就解除了耦合。
 4、具体中介类角色ConcreteMediator. 它实现了抽象中介类角色所定义的通讯功能(此图中是Sendmessage功能)。但此功能是由具体同伴类角色实例ConcreteColleague来调用的,因为在具体中介类角色实例中保存了所有参与活动的具体同伴类角色实例的引用,它们在Mediator中介角色里集中放置与管理。当我们调用相关通讯功能时,通过中介者角色的管理,由它来决定信息通讯的目的地。
下面我们用代码来加以说明

我们有两段程序,一个用于演示中介者模式工作的基本流程,另一个我们使用中介者模式来模拟一个聊天室。
一、基本流程示例代码
1、抽象同伴类角色 AbsPeople

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyMediator
{
    abstract  class AbsPeople
    {
        protected AbsMediator mediator;

#region 构造函数
        public AbsPeople(AbsMediator mediator)
        {
            this.mediator = mediator;
        }
        #endregion
    }
}

2、抽象中介类角色 AbsMediator

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyMediator
{
    //抽象中介类角色AbsMediator
    //在这里定义了需要实现的通讯方法
    abstract  class AbsMediator
    {
        //在Send方法中,传入的是AbsPeople接口,它是具体People类的基类
        public abstract void Send(string message,AbsPeople people);
    }
}

3、具体同伴类角色 Student与Teacher

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyMediator
{
    //定义具体同伴类角色 

    Student类#region Student类
    class Student : AbsPeople
    {
        构造函数#region 构造函数
        public Student(AbsMediator mediator)
            : base(mediator)
        {

        }
        #endregion

        public void Send(string message)
        {
            mediator.Send(message,this);
        }
       
        public void Notify(string message)
        {
            Console.WriteLine("学生收到信息:{0}",message);
        }
    }
    #endregion

    Teacher类#region Teacher类
    class Teacher : AbsPeople
    {
        构造函数#region 构造函数
        public Teacher(AbsMediator mediator)
            : base(mediator)
        {

        }
        #endregion

        public void Send(string message)
        {
            mediator.Send(message, this);
        }

        public void Notify(string message)
        {
            Console.WriteLine("教师收到信息:{0}", message);
        }
    }
    #endregion

}

4、具体中介类角色 RealMediator

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyMediator
{
    class RealMediator: AbsMediator 
    {
        //在Mediator的具体类中融合了所有相关联的People
        private Student _pstudent;
        private Teacher _pteacher;

public Student PStudent
        {
            set { _pstudent = value; }
        }
        public Teacher PB
        {
            set { _pteacher = value; }
        }

public override void Send(string message, AbsPeople people)
        {
            if(people==_pstudent)
            {
                _pteacher.Notify(message);
            }
            if(people==_pteacher)
            {
                _pstudent.Notify(message);
            }
        }
    }
}

5、客户应用

Code
            #region 流程示范
            Console.WriteLine("---------------流程示例-------------");
            RealMediator rm = new RealMediator();
            Student pStudent = new Student(rm);
            Teacher pTeacher = new Teacher(rm);

rm.PStudent = pStudent;
            rm.PB = pTeacher;

pStudent.Send("老师好");
            pTeacher.Send("同学们好.");
            Console.ReadKey();

#endregion

二、中介者模式实现的聊天室
1、抽象同伴类角色  AbsParticipant

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyMediator
{
    //定义抽象同伴类角色 
    //此处定义了两个属性,一个是Name,一个是抽象中介类对象
    public abstract  class AbsParticipant
    {
        ChatRoom属性,它是AbsChatRoom类对象#region ChatRoom属性,它是AbsChatRoom类对象
        private AbsChatRoom _chatroom;
        public AbsChatRoom ChatRoom
        {
            set { _chatroom = value; }
            get { return _chatroom; }
        }
        #endregion

        Name属性#region Name属性
        private string _name;
        public string Name
        {
            get { return _name; }
        }
        #endregion

        构造函数#region 构造函数
        public AbsParticipant(string name)
        {
            this._name = name;
        }
        #endregion

        定义其子类需要实现的功能#region 定义其子类需要实现的功能
        //在此处功能实现时需要用到抽象中介类对象所具备的功能,如下面的AbsParticipant类Send功能的实现就用到了AbsChatRoom类对象所具备的Send功能。
        Send功能#region Send功能
        public void Send(string to,string message)
        {
            _chatroom.Send(_name, to, message); //调用chatroom的Send功能来完成Participant的Send功能,此处的chatroom是一个具体的RealChatRoom
        }
        #endregion

        Receive功能#region Receive功能
        public virtual void Receive(string from, string message)
        {
            Console.WriteLine("{0}to{1}:'{2}'",from,Name,message);
        }
        #endregion
        #endregion
    }
}

2、抽象中介类角色 AbsChatRoom

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyMediator
{
    //定义一个抽象类AbsChatRoom,它是RealChatRoom的基类
    //此处定义了两个需要实现的功能,一个是注册,一个是发送信息
    public  abstract  class AbsChatRoom
    {
        public abstract void Register(AbsParticipant participant);
        public abstract void Send(string from, string to, string message);
    }
}

3、具体同伴类角色  Boy与Girl

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyMediator
{
    //此处定义了两个抽象同伴类角色AbsParticipant的子类,一个是Boy,一个是Girl
    男士Partitcipant类#region 男士Partitcipant类
      public class Boy:AbsParticipant
      {

          public Boy(string name)
              : base(name)
          {

          }
          public override void Receive(string from, string message)
          {
              Console.WriteLine("-------{0}听到:----------------", this.Name);
              base.Receive(from, message);
          }

      }
    #endregion

    女士Participant类#region 女士Participant类
      public   class Girl : AbsParticipant
      {
          public Girl(string name)
              : base(name)
          {

          }
          public override void Receive(string from, string message)
          {
              Console.WriteLine("-------{0}听到:----------------",this.Name);
              base.Receive(from, message);
          }

      }
    #endregion
}

4、具体中介类角色  RealChatRoom

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyMediator
{
    #region 定义一个具体的ChatRoom,它继承自抽象类AbsChatRoom,并实现AbsChatRoom定义的功能
    class RealChatRoom:AbsChatRoom
    {
        #region 定义一个字典,用于管理参加聊天的人员
        private Dictionary<string, AbsParticipant> _participants = new Dictionary<string, AbsParticipant>();
        #endregion

#region 实现注册功能
        public override void Register(AbsParticipant participant)
        {
            //如果新加入一个人,他/她不在当前人员列表中,则把此新人加入到列表中
            if(!_participants.ContainsValue(participant))
            {
                _participants[participant.Name] = participant;
            }
            participant.ChatRoom = this;
        }
        #endregion

#region 实现发送信息功能
        public override void Send(string from, string to, string message)
        {
            AbsParticipant pt = _participants[to];
            
            if(pt!=null)
            { 
                pt.Receive(from, message); //如果有此人,则调用他/她的Receive方法
            }
        }
        #endregion
    }
    #endregion
}

5、客户应用

Code
            #region 聊天室示例
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("---------------聊天室示例-------------");
            RealChatRoom room = new RealChatRoom();

AbsParticipant WangJun = new Boy("王军");
            AbsParticipant ZhouQiang = new Boy("周强");
            AbsParticipant LiWeiDong = new Boy("李卫东");
            AbsParticipant YuanHui = new Boy("袁晖");
            AbsParticipant SunLing = new Girl("孙玲");
            AbsParticipant DenLiLi = new Girl("邓丽丽");

room.Register(WangJun);
            room.Register(ZhouQiang);
            room.Register(LiWeiDong);
            room.Register(YuanHui);
            room.Register(SunLing);
            room.Register(DenLiLi);

WangJun.Send("孙玲", "你好孙玲");  //此处实质是调用RealChatRoom定义的Send功能来完成Send操作
            ZhouQiang.Send("李卫东", "哥们在吗?");
            LiWeiDong.Send("周强", "我才上来,今天工作忙不忙?");
            YuanHui.Send("孙玲", "昨天看到你哥了");
            SunLing.Send("邓丽丽", "作业做完没有?");
            DenLiLi.Send("周强", "你是哪里的?");

Console.ReadKey();
            #endregion

程序如下图:

运行效果如下:
                  

适用性:
    1.一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
    2.一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
    3.想定制一个分布在多个类中的行为,而又不想生成太多的子类。

前往:设计模式学习笔记清单

转载于:https://www.cnblogs.com/wsdj-ITtech/archive/2009/10/09/1579857.html

设计模式学习笔记--Mediator 中介者模式相关推荐

  1. 设计模式学习笔记——享元(Flyweight)模式

    设计模式学习笔记--享元(Flyweight)模式 @(设计模式)[设计模式, 享元模式, flyweight] 设计模式学习笔记享元Flyweight模式 基本介绍 享元案例 类图 实现代码 Big ...

  2. 设计模式学习笔记——单例(Singleton)模式

    设计模式学习笔记--单例(Singleton)模式 @(设计模式)[设计模式, 单例模式, Singleton, 懒汉式, 饿汉式] 设计模式学习笔记单例Singleton模式 基本介绍 单例案例 类 ...

  3. 设计模式学习笔记--Flyweight享元模式

    Flyweight模式也叫享元模式,是由GoF提出的23种设计模式中的一种.Flyweight模式是构造型模式之一,它通过与其他类似对象共享数据来减小内存占用,所以叫享元.   此模式解决的是由于大量 ...

  4. 设计模式学习笔记--享元(Flyweight)模式

    写在模式学习之前 什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式:每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案:当我们碰到模式 ...

  5. 设计模式之略见一斑(Mediator中介者模式)

    设计模式 写道 通常,面向对象的软件开发要求尽可能细致地分配,从而使每个对象都能够独立完成自己的任务.Observer模式通过尽可能缩小一个对象应对其他对象承担的责任范围来支持这种责任分配.而sing ...

  6. C#设计模式学习笔记:(4)建造者模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7614630.html,记录一下学习过程以备后续查用.一.引言在现实生活中,我们经常会遇到一些构成比较复杂的物 ...

  7. 设计模式学习笔记(八)—Template Method模式

    factory模式(包括简单工厂和抽象工厂),Strategy模式,Template method模式是学习Spring框架必不可少的. <设计模式>一书对Template Method模 ...

  8. 设计模式学习笔记(一)之工厂模式、单例模式

    一.工厂模式 (1)简单工厂模式: 1 public interface IProduct { 2 3 public void saleProduct(); 4 5 } 创建一个产品接口,有一个卖产品 ...

  9. 设计模式学习笔记九:原型模式(Prototype Pattern)

    1.概述     意图:我们将已经存在的对象作为原型,用户可以通过复制这些原型创建新的对象.     使用场合:当一个系统应该独立于产品的创建.构造和表示时,可以使用原型模式.在原型模式中,产品的创建 ...

最新文章

  1. Django 数据库
  2. EasyUI中Combox组合框的简单使用
  3. windows 取色器_这款 Windows 10 官方「外挂」让你取色更便捷
  4. libevent源码深度剖析一
  5. arm-2009q1-203-arm-none-linux-gnueabi.bin安装方法
  6. 标准c语言有几个关键字,C语言有多少个关键字
  7. easyui中动态使datebox、combobox为只读状态
  8. 使用JWT来实现单点登录功能
  9. Spark与MR的区别
  10. Fedora 安装 WPS
  11. BrcmPatchRAM 黑苹果WiFi无线网卡蓝牙驱动
  12. 感性电路电流计算_家用空开怎么计算?怎么选择?
  13. WPS Word添加或删除页面上/下方的横线
  14. C++中toupper、tolower 、isalpha、isalnum、isdigit、islower、isupper、isblank、isspace的用法
  15. 解析Esri WebScene
  16. APUE-文件和目录(六)函数ftw和nftw
  17. 第五代选择器Icarus
  18. uniapp 电商app签到功能实现
  19. 生物智能与AI——关乎创造、关乎理解(上) 1
  20. 互联网公司为什么普遍996而不是666?

热门文章

  1. 黑色幽默:“新知青”电影《走着瞧》首映
  2. MFC界面编程新思路--模仿MATLAB式的界面
  3. java setlt;intgt;_java使用Nagao算法实现新词发现、热门词的挖掘
  4. 机器人J中WPR_北方工业大学服务机器人研究项目介绍
  5. oracle主机名的脚本,一个开启Oracle服务和更改主机名的脚本-Oracle
  6. hal库开启中断关中断_stm32的HAL库开发学习笔记之外部中断
  7. Unity游戏开发——C#特性Attribute与自动化
  8. Deep Learning运行所需的硬件配置(转)
  9. PCA的原理及MATLAB实现
  10. python类和实例化