C#设计模式读书笔记之中介者模式(Mediator pattern)

26 篇文章 16 订阅

中介者模式(Mediator pattern)【使用频率:★★☆☆☆】

1.概述:用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式是“迪米特法则”的一个典型应用

2. 模式中的角色

2.1 Mediator(抽象中介者):它定义一个接口,该接口用于与各同事对象之间进行通信。

2.2 ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,它维持了对各个同事对象的引用。

2.3 Colleague(抽象同事类):它定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现,同时它维持了一个对抽象中介者类的引用,其子类可以通过该引用来与中介者通信。

2.4 ConcreteColleague(具体同事类):它是抽象同事类的子类;每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中声明的抽象方法。

3.1 模式类图

3.2 中介者代码实现:

using System;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            //一个房东、一个租房者、一个中介机构
            MediatorStructure mediator = new MediatorStructure();

            //房主和租房者只需要知道中介机构即可
            HouseOwner houseOwner = new HouseOwner("张三", mediator);
            Tenant tenant = new Tenant("李四", mediator);

            //中介结构要知道房东和租房者的信息
            mediator.SetHouseOwner(houseOwner);
            mediator.SetTenant(tenant);

            tenant.Constact("听说你那里有三室的房子出租?");
            houseOwner.Constact("是的!请问你需要租吗?");

            Console.ReadLine();
        }
    }

    /// <summary>
    /// 抽象中介者
    /// </summary>
    public abstract class Mediator
    {
        //声明一个联络方法
        public abstract void Constact(string message, Person person);
    }

    /// <summary>
    /// 具体中介者对象
    /// </summary>
    public class MediatorStructure : Mediator
    {
        //首先中介结构必须知道所有房主和租房者的信息
        private HouseOwner houseOwner;
        private Tenant tenant;

        public HouseOwner GetHouseOwner()
        {
            return houseOwner;
        }

        public void SetHouseOwner(HouseOwner houseOwner)
        {
            this.houseOwner = houseOwner;
        }

        public Tenant GetTenant()
        {
            return tenant;
        }

        public void SetTenant(Tenant tenant)
        {
            this.tenant = tenant;
        }

        public override void Constact(string message, Person person)
        {
            if (person == houseOwner)
            {
                //如果是房东,则租房者获得信息
                tenant.GetMessage(message);
            }
            else
            {
                //反之,则是房东获得信息
                houseOwner.GetMessage(message);
            }
        }
    }

    /// <summary>
    /// 抽象同事对象,维持了一个对抽象中介者类的引用
    /// </summary>
    public abstract class Person
    {
        protected string name;
        protected Mediator mediator;

        public Person(string name, Mediator mediator)
        {
            this.name = name;
            this.mediator = mediator;
        }
    }

    /// <summary>
    /// 具体同事类:房东
    /// </summary>
    public class HouseOwner : Person
    {

        public HouseOwner(string name, Mediator mediator) : base(name, mediator)
        {
        }

        // 先与中介者通信,通过中介者来间接完成与其他同事类的通信
        public void Constact(string message)
        {
            mediator.Constact(message, this);
        }

        // 获取信息
        public void GetMessage(string message)
        {
            Console.WriteLine("房东:" + name + ",获得信息:" + message);
        }
    }

    /// <summary>
    /// 具体同事类:租房者
    /// </summary>
    public class Tenant : Person
    {

        public Tenant(string name, Mediator mediator) : base(name, mediator)
        {
        }

        // 先与中介者通信,通过中介者来间接完成与其他同事类的通信
        public void Constact(string message)
        {
            mediator.Constact(message, this);
        }

        // 获取信息
        public void GetMessage(string message)
        {
            Console.WriteLine("租房者:" + name + ",获得信息:" + message);
        }
    }
}

4 模式优缺点

4.1 优点

  • 简化了对象之间的关系,将系统的各个对象之间的相互关系进行封装,将各个同事类解耦,使系统成为松耦合系统。
  • 减少了子类的生成。
  • 可以减少各同事类的设计与实现。

4.2 缺点

由于中介者对象封装了系统中对象之间的相互关系,导致其变得非常复杂,使得系统维护比较困难。

 

5.适用场景

  • 系统中对象之间存在比较复杂的引用关系,导致他们之间的依赖关系结构混乱而且难以复用该对象。
  • 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值