日志

设计模式-行为型-中介者模式

 来源    2019-10-09    1  

中介者模式(Mediator):

  在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室、QQ群、短信平台和房产中介。不论是QQ游戏还是QQ群,它们都是充当一个中间平台,QQ用户可以登录这个中间平台与其他QQ用户进行交流,如果没有这些中间平台,我们如果想与朋友进行聊天的话,可能就需要当面才可以了。电话、短信也同样是一个中间平台,有了这个中间平台,每个用户都不要直接依赖与其他用户,只需要依赖这个中间平台就可以了,一切操作都由中间平台去分发。中介者模式,定义了一个中介对象来封装一系列对象之间的交互关系。中介者使各个对象之间不需要显式地相互引用,从而使耦合性降低,而且可以独立地改变它们之间的交互行为。

  

中介者模式的角色:

  

  1)抽象中介者(Mediator):定义了同事对象到中介者对象的接口。

  2)具体中介者(ConcreteMediator):实现抽象类的方法,它需要知道具体的同事类并从具体同事类接受消息,向具体同事对象发出命令。

  3)抽象同事类(Colleague):定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。

  4)具体同事类(ConcreteColleague):每个具体同事类只知道自己的行为,而不了解其他同事类的情况,但它们认识中介者对象。

示例:

  以现实生活中打牌为例,若不使用中介者模式。

/// <summary>
/// 抽象牌友类
/// </summary>
public abstract class AbstractCardPartner
{
    public int Money { get; set; }

    public abstract void ChangeMoney(int money, AbstractCardPartner other);
}

/// <summary>
/// 牌友A
/// </summary>
public class PartnerA : AbstractCardPartner
{
    public override void ChangeMoney(int money, AbstractCardPartner other)
    {
        Money += money;
        other.Money -= money;
    }
}

/// <summary>
/// 牌友B
/// </summary>
public class PartnerB : AbstractCardPartner
{
    public override void ChangeMoney(int money, AbstractCardPartner other)
    {
        Money += money;
        other.Money -= money;
    }
}

internal class Program
{
    private static void Main(string[] args)
    {
        AbstractCardPartner A = new PartnerA();
        A.Money = 20;
        AbstractCardPartner B = new PartnerB();
        B.Money = 20;

        // A赢了B的钱减少
        A.ChangeMoney(5, B);
        Console.WriteLine("A 现在的钱是:{0}", A.Money); // 应该是25
        Console.WriteLine("B 现在的钱是:{0}", B.Money); // 应该是15

        // B赢了A的钱减少
        B.ChangeMoney(10, A);
        Console.WriteLine("A 现在的钱是:{0}", A.Money); // 应该是15
        Console.WriteLine("B 现在的钱是:{0}", B.Money); // 应该是25
    }
}

  这样的实现确实解决了上面场景中的问题,并且使用了抽象类使具体牌友A和牌友B都依赖于抽象类,从而降低了同事类之间的耦合度。但是如果其中牌友A发生变化时,此时就会影响到牌友B的状态,如果涉及的对象变多的话,这时候某一个牌友的变化将会影响到其他所有相关联的牌友状态。例如牌友A算错了钱,这时候牌友A和牌友B的钱数都不正确了,如果是多个人打牌的话,影响的对象就会更多。这时候就会思考——能不能把算钱的任务交给程序或者算数好的人去计算呢,这时候就有了我们QQ游戏中的欢乐斗地主等牌类游戏了。

/// <summary>
/// 抽象牌友类
/// </summary>
public abstract class AbstractCardPartner
{
    protected AbstractMediator mediator;

    public int Money { get; set; }

    public abstract void Change(int money, AbstractMediator mediator);
}

/// <summary>
/// 牌友A
/// </summary>
public class PartnerA : AbstractCardPartner
{
    public PartnerA(int money)
    {
        Money = money;
    }

    public override void Change(int money, AbstractMediator mediator)
    {
        Console.WriteLine($"{nameof(PartnerA)}赢了");
        mediator.Change(money, this);
    }
}

/// <summary>
/// 牌友B
/// </summary>
public class PartnerB : AbstractCardPartner
{
    public PartnerB(int money)
    {
        Money = money;
    }

    public override void Change(int money, AbstractMediator mediator)
    {
        Console.WriteLine($"{nameof(PartnerB)}赢了");
        mediator.Change(money, this);
    }
}

/// <summary>
/// 牌友B
/// </summary>
public class PartnerC : AbstractCardPartner
{
    public PartnerC(int money)
    {
        Money = money;
    }

    public override void Change(int money, AbstractMediator mediator)
    {
        Console.WriteLine($"{nameof(PartnerC)}赢了");
        mediator.Change(money, this);
    }
}

/// <summary>
/// 抽象中介者类
/// </summary>
public abstract class AbstractMediator
{
    public abstract void Register(AbstractCardPartner cardPartner);

    // cardPartner赢钱
    public abstract void Change(int money, AbstractCardPartner cardPartner);
}

public class Mediator : AbstractMediator
{
    private List<AbstractCardPartner> list = new List<AbstractCardPartner>();

    public override void Register(AbstractCardPartner cardPartner)
    {
        list.Add(cardPartner);
    }

    public override void Change(int money, AbstractCardPartner cardPartner)
    {
        foreach (var item in list)
        {
            if (item != cardPartner)
            {
                cardPartner.Money += money;
                item.Money -= money;
            }
        }
    }
}

internal class Program
{
    private static void Main(string[] args)
    {
        AbstractMediator mediator = new Mediator();
        AbstractCardPartner A = new PartnerA(20);
        AbstractCardPartner B = new PartnerB(20);
        AbstractCardPartner C = new PartnerC(20);

        mediator.Register(A);
        mediator.Register(B);
        mediator.Register(C);

        // A赢了
        A.Change(5, mediator);
        Console.WriteLine("A 现在的钱是:{0}", A.Money); // 应该是30
        Console.WriteLine("B 现在的钱是:{0}", B.Money); // 应该是15
        Console.WriteLine("C 现在的钱是:{0}", C.Money); // 应该是15
    }
}

  在上面的实现代码中,抽象中介者类保存了两个抽象牌友类,如果新添加一个牌友类似时,此时就不得不去更改这个抽象中介者类。可以结合观察者模式来解决这个问题,即抽象中介者对象保存抽象牌友的类别,然后添加Register和UnRegister方法来对该列表进行管理,然后在具体中介者类中修改AWin和BWin方法,遍历列表,改变自己和其他牌友的钱数。这样的设计还是存在一个问题——即增加一个新牌友时,此时虽然解决了抽象中介者类不需要修改的问题,但此时还是不得不去修改具体中介者类,即添加CWin方法,我们可以采用状态模式来解决这个问题。

  在写中介者模式的时候,我发现我将其写成了观察者模式,后来仔细研究发现两者还是有区别的:

    中介者模式主要是起到一个协调的作用,它知道所有的同事类且同事类含有中介者对象,即我有事通知你,你帮我协调一下。

    而观察者模式侧重在当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。

中介者模式的优缺点:

  优点:

    1)简化了对象之间的关系,将系统的各个对象之间的相互关系进行封装,将各个同事类解耦,使得系统变为松耦合。

    2)提供系统的灵活性,使得各个同事对象独立而易于复用。

  缺点:

    1)中介者模式中,中介者角色承担了较多的责任,所以一旦这个中介者对象出现了问题,整个系统将会受到重大的影响。

    2)新增加一个同事类时,不得不去修改抽象中介者类和具体中介者类,此时可以使用观察者模式和状态模式来解决这个问题。

中介者使用的场景:

  1)一组定义良好的对象,现在要进行复杂的相互通信。

  2)想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

参考:https://www.runoob.com/design-pattern/mediator-pattern.html

相关文章
设计模式(17)--Mediator(中介者模式)行为型
日志 作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可 ...
C#设计模式之十七中介者模式(Mediator Pattern)行为型
日志原文:C#设计模式之十七中介者模式(Mediator Pattern)[行为型]一.引言   今天我们开始讲"行为型"设计模式的第五个模式,该模式是[中介者模式],英文名称是:Me ...
设计模式学习之中介者模式(Mediator,行为型模式)(18)
日志转载地址:https://www.cnblogs.com/zhili/p/MediatorPattern.html 一.引言 在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室.QQ群和短 ...
设计模式-创建型-抽象工厂模式
日志前一章节,我们介绍了简单工厂模式以及工厂方法模式,但是这两种模式都存在一定的局限性,只能生产某一类型下的某一种产品,如果需求变更,同类型下出现了不同的产品,比如芝士披萨不仅有口味上的不同,同时存在外观 ...
学习设计模式第二十 - 中介者模式
日志示例代码来自DoFactory. 概述 中介者模式出现的背景是,尽管将一个系统分割成许多对象通常可以增加其复用性,但是对象间相互连接的激增又会降低其可复用性.大量的连接使得一个对象不可能在没有其他对象 ...
设计模式读书笔记-----中介者模式
日志      在我们的生活中处处充斥着"中介者",比如你租房.买房.出国留学.找工作.旅游等等可能都需要那些中介者的帮助,同时我们也深受其害,高昂的中介费,虚假信息.在地球上最大的中 ...
设计模式 创建型 工厂方法模式
日志工厂方法模式是类的创建模式,又叫做虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式. 工厂方法模式的用意是定义一个创建产品对象的工厂 ...
设计模式 创建型 简单工厂模式
日志参考:<JAVA与模式>之简单工厂模式 简单工厂模式是对象的创建模式,又叫做静态工厂方法(Static Factory Method)模式.简单工厂模式是由一个工厂对象决定创建出哪一种产品 ...
Java设计模式系列之中介者模式
日志中介者模式(Mediator)的定义 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 中介者模式(Mediator)的适 ...
Java设计模式学习记录-中介者模式
日志前言 中介者模式听名字就能想到也是一种为了解决耦合度的设计模式,其实中介者模式在结构上与观察者.命令模式十分相像:而应用目的又与结构模式“门面模式”有些相似.但区别于命令模式的是大多数中介者角色对于客 ...
设计模式 - 17 之中介者模式(Mediator)
日志1.模式简介 中介者模式的定义: 用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显式地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互. 中介者模式中的组成部分: 同事类:如果两 ...
java设计模式-----17、中介者模式
日志概念: Mediator模式也叫中介者模式,是由GoF提出的23种软件设计模式的一种.Mediator模式是行为模式之一,在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中, ...
设计模式のMediatorPattern(中介者模式)----行为模式
日志一.产生背景 从生活中的例子可以看出,不论是QQ游戏还是QQ群,它们都是充当一个中间平台,QQ用户可以登录这个中间平台与其他QQ用户进行交流,如果没有这些中间平台,我们如果想与朋友进行聊天的话,可能就 ...
python设计模式---创建型之工厂模式
日志# coding = utf-8 from abc import ABCMeta, abstractmethod # 简单工厂模式 class Animal(metaclass=ABCMeta): @ ...
设计模式学习--------11.中介者模式学习
日志场景:        构建一个部门管理和人员管理的模块.比如一个部门可以有多个人,一个人可以属于多个部门.        现增加一些功能:        1.部门被撤销,就需要通知清除这个部门下面的所 ...
设计模式-行为型-职责链模式
日志职责链模式(Chain of Responsibility): 在现实生活中,常常会出现这样的事例:一个请求需要多个对象处理,但每个对象的处理条件或权限不同.如公司员工报销差旅费,可审批的领导有部分负 ...
设计模式 17、中介者模式
日志package com.shejimoshi.behavioral.Mediator; /** * 功能:领导者接口 * 时间:2016年3月5日下午10:41:35 * 作者:cutter_poin ...
《JAVA设计模式》之中介者模式(Mediator)
日志在阎宏博士的<JAVA与模式>一书中开头是这样描述调停者(Mediator)模式的: 调停者模式是对象的行为模式.调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显引用.从 ...
行为型---中介者模式(Mediator Pattern)
日志中介者模式的定义 中介者模式,定义了一个中介对象来封装一系列对象之间的交互关系.中介者使各个对象之间不需要显式地相互引用,从而使耦合性降低,而且可以独立地改变它们之间的交互行为. 中介者模式的结构 从 ...