1. 程式人生 > >Head First設計模式之中介者模式

Head First設計模式之中介者模式

函數 padding sta sin color 系列文章 自己的 技術 接口

一、定義

又稱為調停者模式,定義一個中介對象來封裝系列對象之間的交互。中介者使各個對象不需要顯示地相互引用,從而使其耦合性松散,而且可以獨立地改變他們之間的交互。

二、結構

技術分享

組成:

  ● 抽象中介者(Mediator)角色:定義統一的接口用於各同事角色之間的通信,其中主要方法是一個(或多個)事件方法。

  ● 具體中介者(ConcreteMediator)角色:實現了抽象中介者所聲明的事件方法。具體中介者知曉所有的具體同事類,並負責具體的協調各同事對象的交互關系。

  ● 抽象同事類(Colleague)角色:定義出中介者到同事角色的接口。同事角色只知道中介者而不知道其余的同事角色。與其他的同事角色通信的時候,一定要通過中介者角色協作。

  ● 具體同事類(ConcreteColleague)角色:所有的具體同事類均從抽象同事類繼承而來。實現自己的業務,在需要與其他同事通信的時候,就與持有的中介者通信,中介者會負責與其他的同事交互。

代碼結構

 //抽象中介者類
    public interface IMediator
    {
        /**
         * 同事對象在自身改變的時候來通知中介者的方法
         * 讓中介者去負責相應的與其他同事對象的交互
         */
        void Changed(Colleague c);
    }

    //抽象同事類
public abstract class Colleague { //持有一個中介者對象 private IMediator _mediator; /** * 構造函數 */ public Colleague(IMediator mediator) { this._mediator = mediator; } /** * 獲取當前同事類對應的中介者對象
*/ public IMediator GetMediator() { return _mediator; } } //具體中介者類 public class ConcreteMediator : IMediator { //持有並維護同事A private ConcreteColleagueA _colleagueA; //持有並維護同事B private ConcreteColleagueB _colleagueB; public void SetColleagueA(ConcreteColleagueA colleagueA) { this._colleagueA = colleagueA; } public void SetColleagueB(ConcreteColleagueB colleagueB) { this._colleagueB = colleagueB; } public void Changed(Colleague c) { /** * 某一個同事類發生了變化,通常需要與其他同事交互 * 具體協調相應的同事對象來實現協作行為 */ } } //具體同事類 public class ConcreteColleagueA : Colleague { public ConcreteColleagueA(IMediator mediator) : base(mediator) { } /** * 示意方法,執行某些操作 */ public void Operation() { //在需要跟其他同事通信的時候,通知中介者對象 GetMediator().Changed(this); } } public class ConcreteColleagueB : Colleague { public ConcreteColleagueB(IMediator mediator) : base(mediator) { } /** * 示意方法,執行某些操作 */ public void Operation() { //在需要跟其他同事通信的時候,通知中介者對象 GetMediator().Changed(this); } }

三、適用場景

1、系統中對象之間存在比較復雜的引用關系,導致它們之間的依賴關系結構混亂而且難以復用該對象。

2、想通過一個中間類來封裝多個類中的行為,而又不想生成太多的子類。

應用實例

1、中國加入 WTO 之前是各個國家相互貿易,結構復雜,現在是各個國家通過 WTO 來互相貿易。

2、機場調度系統。

3、MVC 框架,其中C(控制器)就是 M(模型)和 V(視圖)的中介者。

四、優缺點

  優點: 1、降低了類的復雜度,將一對多轉化成了一對一。 2、各個類之間的解耦。 3、符合迪米特原則。

  缺點:中介者會龐大,變得復雜難以維護。

五、實現

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatterns.Mediator
{
    class Program
    {
        static void Main(string[] args)
        {
            MessageMediator mediator = new MessageMediator();

            ConcreteColleagueA a = new ConcreteColleagueA(mediator, "A");
            ConcreteColleagueB b = new ConcreteColleagueB(mediator, "B");
            ConcreteColleagueC c = new ConcreteColleagueC(mediator, "C");

            mediator.SetColleagueA(a);
            mediator.SetColleagueB(b);
            mediator.SetColleagueC(c);

            mediator.Chat(a, "中午吃啥飯?");
            Console.WriteLine("====");

            mediator.Chat(b, "我想吃刀削面");
            Console.WriteLine("====");

            mediator.Chat(c, "我也想吃刀削面");
            Console.WriteLine("====");
            
            mediator.Chat(a, "行,那中午一起去吃刀削面吧");
        }
    }

    //抽象中介者類
    public interface IMediator
    { 
        void Chat(Colleague c, string message);
    }

    //抽象同事類
    public abstract class Colleague
    {
        private string name;
        //持有一個中介者對象
        private IMediator _mediator;
        
        public Colleague(IMediator mediator, string name)
        {
            this._mediator = mediator;
            this.name = name;
        }
        /**
         * 獲取當前同事類對應的中介者對象
         */
        public IMediator GetMediator()
        {
            return _mediator;
        }

        /**
         * 獲取昵稱
         */
        public string getName()
        {
            return name;
        }

        /**
         * 接收消息
         */
        public abstract void receive(string message);

        /**
         * 發送消息
         */
        public abstract void send(string message);
    }

    //具體中介者類
    public class MessageMediator : IMediator
    {
        //持有並維護同事A
        private ConcreteColleagueA _colleagueA;
        //持有並維護同事B
        private ConcreteColleagueB _colleagueB;

        private ConcreteColleagueC _colleagueC;

        public void SetColleagueA(ConcreteColleagueA colleagueA)
        {
            this._colleagueA = colleagueA;
        }

        public void SetColleagueB(ConcreteColleagueB colleagueB)
        {
            this._colleagueB = colleagueB;
        }
        public void SetColleagueC(ConcreteColleagueC colleagueC)
        {
            this._colleagueC = colleagueC;
        }

        public void Chat(Colleague c, string message)
        {
            if (_colleagueA != null)
            {
                _colleagueA.send(message);
                _colleagueB.receive(message);
                _colleagueC.receive(message);
            }
            else if (_colleagueB != null) {
                _colleagueB.send(message);
                _colleagueA.receive(message);
                _colleagueC.receive(message);
            } else if (_colleagueC != null) {
                _colleagueC.send(message);
                _colleagueA.receive(message);
                _colleagueB.receive(message);
            }
        }
    }

    //具體同事類
    public class ConcreteColleagueA : Colleague
    {

        public ConcreteColleagueA(IMediator mediator, string name) : base(mediator, name)
        {
        }
        /**
         * 示意方法,執行某些操作
         */
        public void Operation(string message)
        {
            //在需要跟其他同事通信的時候,通知中介者對象
            GetMediator().Chat(this, message);
        }

        public override void receive(String message)
        {
            Console.WriteLine("【A】收到消息:【" + message + "");
        }

        public override void send(String message)
        {
            Console.WriteLine("【A】發出消息:【" + message + "");
        }
    }
    public class ConcreteColleagueB : Colleague
    {

        public ConcreteColleagueB(IMediator mediator, string name) : base(mediator, name)
        {
        }
        /**
         * 示意方法,執行某些操作
         */
        public void Operation(string message)
        {
            //在需要跟其他同事通信的時候,通知中介者對象
            GetMediator().Chat(this, message);
        }

        public override void receive(String message)
        {
            Console.WriteLine("【B】收到消息:【" + message + "");
        }

        public override void send(String message)
        {
            Console.WriteLine("【B】發出消息:【" + message + "");
        }
    }


    public class ConcreteColleagueC : Colleague
    {

        public ConcreteColleagueC(IMediator mediator, string name) : base(mediator, name)
        {
        }
        /**
         * 示意方法,執行某些操作
         */
        public void Operation(string message)
        {
            //在需要跟其他同事通信的時候,通知中介者對象
            GetMediator().Chat(this, message);
        }

        public override void receive(String message)
        {
            Console.WriteLine("【C】收到消息:【" + message + "");
        }

        public override void send(String message)
        {
            Console.WriteLine("【C】發出消息:【" + message + "");
        }
    }
}

結果

【A】發出消息:【中午吃啥飯?】
【B】收到消息:【中午吃啥飯?】
【C】收到消息:【中午吃啥飯?】
====
【A】發出消息:【我想吃刀削面】
【B】收到消息:【我想吃刀削面】
【C】收到消息:【我想吃刀削面】
====
【A】發出消息:【我也想吃刀削面】
【B】收到消息:【我也想吃刀削面】
【C】收到消息:【我也想吃刀削面】
====
【A】發出消息:【行,那中午一起去吃刀削面吧】
【B】收到消息:【行,那中午一起去吃刀削面吧】
【C】收到消息:【行,那中午一起去吃刀削面吧】

參考:

http://www.cnblogs.com/JsonShare/p/7263876.html

http://www.runoob.com/design-pattern/mediator-pattern.html


歡迎閱讀本系列文章:Head First設計模式之目錄

Head First設計模式之中介者模式