设计模式学习笔记--Mediator 中介者模式

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

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



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

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

ContractedBlock.gifExpandedBlockStart.gifCode
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

ContractedBlock.gifExpandedBlockStart.gifCode
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

ContractedBlock.gifExpandedBlockStart.gifCode
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyMediator
ExpandedBlockStart.gifContractedBlock.gif
{
    
//定义具体同伴类角色 

ContractedSubBlock.gifExpandedSubBlockStart.gif    
Student类#region Student类
    
class Student : AbsPeople
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
ContractedSubBlock.gifExpandedSubBlockStart.gif        
构造函数#region 构造函数
        
public Student(AbsMediator mediator)
            : 
base(mediator)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{

        }

        
#endregion


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

       
        
public void Notify(string message)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            Console.WriteLine(
"学生收到信息:{0}",message);
        }

    }

    
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif    
Teacher类#region Teacher类
    
class Teacher : AbsPeople
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
ContractedSubBlock.gifExpandedSubBlockStart.gif        
构造函数#region 构造函数
        
public Teacher(AbsMediator mediator)
            : 
base(mediator)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{

        }

        
#endregion


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


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

    }

    
#endregion


}

4、具体中介类角色 RealMediator

ContractedBlock.gifExpandedBlockStart.gifCode
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、客户应用

ContractedBlock.gifExpandedBlockStart.gifCode
            #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 
ContractedBlock.gifExpandedBlockStart.gifCode
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

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

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
Name属性#region Name属性
        
private string _name;
        
public string Name
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _name; }
        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
构造函数#region 构造函数
        
public AbsParticipant(string name)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this._name = name;
        }

        
#endregion


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

        
#endregion


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

        
#endregion

        
#endregion

    }

}

2、抽象中介类角色 AbsChatRoom

ContractedBlock.gifExpandedBlockStart.gifCode
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

ContractedBlock.gifExpandedBlockStart.gifCode
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

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

          
public Boy(string name)
              : 
base(name)
ExpandedSubBlockStart.gifContractedSubBlock.gif          
{

          }

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


      }

    
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif    
女士Participant类#region 女士Participant类
      
public   class Girl : AbsParticipant
ExpandedSubBlockStart.gifContractedSubBlock.gif      
{
          
public Girl(string name)
              : 
base(name)
ExpandedSubBlockStart.gifContractedSubBlock.gif          
{

          }

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


      }

    
#endregion

}

4、具体中介类角色  RealChatRoom

ContractedBlock.gifExpandedBlockStart.gifCode
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、客户应用 

ContractedBlock.gifExpandedBlockStart.gifCode
            #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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/264185.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue.js + Nuxt.js 项目中使用 Vee-validate 表单校验

vee-validate 是为 Vue.js 量身打造的表单校验框架&#xff0c;允许您校验输入的内容并显示对应的错误提示信息。它内置了很多常见的校验规则&#xff0c;可以组合使用多种校验规则&#xff0c;大部分场景只需要配置就能实现开箱即用&#xff0c;还支持自定义正则表达式。而且支…

Linux中fork()函数详解

参考地址 1.对fork函数的认识&#xff1a; 一个进程&#xff0c;包括代码、数据和分配给进程的资源。fork&#xff08;&#xff09;函数通过系统调用创建一个与原来进程几乎完全相同的进程&#xff0c; 也就是两个进程可以做完全相同的事&#xff0c;但如果初始参数或者传入的变…

Android学习之PopupWindow

Android的对话框有两种&#xff1a;PopupWindow和AlertDialog。 详细说明如下&#xff1a; AlertDialog是非阻塞式对话框&#xff1a;AlertDialog弹出时&#xff0c;后台还可以做事情&#xff1b; AlertDialog的位置固定&#xff0c;而PopupWindow的位置可以随意&#xff1b; A…

Programming C#.Classes and Objects.只读字段

只读字段 当字段声明中含有 readonly 修饰符时&#xff0c;该声明所引入的字段为只读字段。给只读字段的直接赋值只能作为声明的组成部分出现&#xff0c;或在同一类中的实例构造函数或静态构造函数中出现。&#xff08;在这些上下文中&#xff0c;只读字段可以被多次赋值。&am…

xgboost 一般多少棵树_大白话人工智能算法-第32节集成学习之通俗理解XGBoost原理和过程...

本节讲解XGBoost的原理~目录1、回顾&#xff1a;1.1 有监督学习中的相关概念1.2 回归树概念1.3 树的优点2、怎么训练模型&#xff1a;2.1 案例引入2.2 XGBoost目标函数求解3、XGBoost中正则项的显式表达4、如何生长一棵新的树&#xff1f;5、xgboost相比原始GBDT的优化&#xf…

css文件修改后没变化 static_Go Web编程使用Go语言创建静态文件服务器

上篇关于Go模板库应用实践的文章最后我们留下一个问题&#xff0c;页面模板是通过 CDN引用的 BootStrap的 css&#xff0c; js文件。到目前位置我们的服务器还无法伺服客户端的静态文件请求把服务器磁盘上的文件响应给客户端。使用和配置过 Nginx服务器的一定知道 Nginx天然支持…

【linux】学习2

鸟哥那本书的第6章 文件权限&#xff1a; ^ ^ ^ ^ ^ ^ ^ 1 2 3 4 5 6 7 文件有 文件所有者、文件所属用户组 的概念如上图. 1. 十个字母表示文件…

IE 8 开发人员工具详解 【转载】

我的体会&#xff0c;IE 8 较之前面的的版本还是有不少改进的。使用体验上好很多&#xff0c;速度也不错。IE 要继续加油&#xff0c; 对于网页开发人员&#xff0c;IE8也提供了一个所谓的开发人员工具&#xff0c;通过F12可以调用出来 关于这套工具的使用细节&#xff0c;我就…

scrollwidth ,clientwidth ,offsetwidth 三者的区别

clientwidth:内容可视区域的宽度 offsetwidth:元素整体宽度 scrollwidth:实际内容的宽度 转载于:https://www.cnblogs.com/cuijin-book/p/10760656.html

python运算符与表达式

2019独角兽企业重金招聘Python工程师标准>>> 运算符用于连接两个相同类型的序列&#xff0c;s*n用于创建一个序列的n个副本。但是这些都是仅仅复制元素引用的浅复制。 例&#xff1a; a[3,4,5] b[a] c2*b 则c[[3,4,5],[3,4,5]] a[0]-7; 则c[[-7,4,5],[-7,4,5]]. 也…

phper必知必会之类库自动加载的七种方式(三)

## php自动加载 下面显示例子的文件目录结构图 一、没有使用命名空间的几种实现 test/oneClass.php class oneClass{public function show(){echo "这里是oneClass.php的show方法<br/>";}} test/twoClass.php <?phpclass twoClass{public function show(){…

c++ 箭头符号怎么打_焊接图纸符号标注图解示例,焊接符号标注实例及方法

基本坡口符号坡口符号(注&#xff1a;图中“破”应为“坡”)焊接图纸符号标注图解示例焊接符号标注实例及方法在焊接结构图样上&#xff0c;焊接方法可按国家标准GB5185-85的规定用阿拉伯效字表示&#xff0c;标注在指引线的尾部。常用焊接方法代号见表3-9所示。如果是组合焊接…

演示: GTS流量×××和CAR流量监管的效果及相关实践计划

演示&#xff1a; GTS流量和CAR流量监管的效果及相关实践计划演示目标&#xff1a;1 理解clock rate(时钟频率)和bandwidth&#xff08;带宽&#xff09;与接入速率的关系2 在模拟运营商的接入路由器ISP上配置CAR监管用户流量到认购速率64K3 取证模拟的企业网络以128K的接入速率…

跨线程访问控件

【转帖】 我们在做winform应用的时候&#xff0c;大部分情况下都会碰到使用多线程控制界面上控件信息的问题。然而我们并不能用传统方法来做这个问题&#xff0c;下面我将详细的介绍。 首先来看传统方法&#xff1a; public partial class Form1 : Form { public Fo…

解析Nginx负载均衡

摘要&#xff1a;对于一个大型网站来说&#xff0c;负载均衡是永恒的话题。随着硬件技术的迅猛发展&#xff0c;越来越多的负载均衡硬件设备涌现出来&#xff0c;如F5 BIG-IP、Citrix NetScaler、Radware等等&#xff0c;虽然可以解决问题&#xff0c;但其高昂的价格却往往令人…

深圳办理cdn经营许可证_深圳危化品经营许可证申请流程怎么申请?办理危化学品经营许可证...

随着深圳地区慢慢的进入了产业整合和城市规划规范化的运营中&#xff0c;很多涉及到生产的公司都逐渐被有效的整合在一起了&#xff0c;而随着深圳地区越发有效的整合生产规划&#xff0c;很多地区都逐渐的在将涉及到危险化学品生产和经营的企业都进行合理的管制&#xff0c;在…

Discuz!NT 缓存设计简析 [原创]

作为一个社区类型软件&#xff0c;大并发支持和高效稳定运行永远是“硬道理”&#xff0c;而有效安全的使用缓存恰恰能起到事倍功半的效果。而.NET本身所提供的缓存机制又显得过于“单薄”&#xff0c;比如说订制不太灵活方便, 缓存对象之间层次感不强, 使用时缺乏统一的管理等…

VSCode从下载到配置Ubuntu系统

Visual Studio Code从下载到配置Ubuntu系统 一、下载和安装Visual Studio Code 1、进入Visual Studio Code官网&#xff08;Visual Studio Code - Code Editing. Redefined&#xff09;&#xff0c;点击箭头所指地方下载红框内的安装包&#xff1b; 2、因为是国外网址下载&am…

python 写入excel 日期_Python实例:excel文档写入操作

来自PythonABC.org老师的课程很好&#xff0c;但是每个视频都蛮长的&#xff0c;听着听着就有些晕乎&#xff0c;所以根据视频自己整理了一下&#xff0c;以便记录学习使用Python实现excel的文档写操作import openpyxl from openpyxl.utils import get_column_letterwb openpy…