設計模式(十七)中介者

冬先生發表於2023-12-18

一、定義

義一個物件來封裝一系列的物件互動。中介者模式使各物件不需要顯示地相互引用,從而使其耦合鬆散,而且可以讓你相對獨立地改變它們之間的互動。中介者模式又稱為調停模式,它是一種物件說行為型模式。

二、描述

在中介者模式中,引入了用於協調其他物件/類之間的相互呼叫的中介者類,為了讓系統具有更好的靈活性和可擴充套件性,通常還提供了抽象中介者,包含以下四個角色:1、Mediator(抽象中介者):它定義了一個介面,該介面用於與各同事物件之間進行通訊。
2、ConcreteMediator(具體中介者):它是抽象中介者的子類,透過協調各個同事物件來實現協作行為,維持了各個同事物件的引用。
3、Colleague(抽象同事類):它定義了各個同事類公有的方法,並宣告瞭一些抽象方法來供子類實現,同時維持了一個對抽象中介者類的引用,其子類可以透過該引用來與中介者通訊。
4、ConcreteColleague(具體同事類):它是抽象同事類的子類,每一個同事物件需要和其他物件通訊時,先與中介者物件通訊,透過中介者來間接完成與其他同事類的通訊,在具體同事類中實現了在抽象同事類中宣告的抽象方法。

三、例子

X公司欲開發一套CRM系統,其中包含一個客戶資訊管理模組,介面包含了按鈕、文字框、列表框、下拉框等多個元件,增加或刪除一個客戶,各元件均會發生聯動效果,較為複雜。
Mediator:抽象中介者

public abstract class Mediator
{
    public abstract void ComponenetChanged(Component c);
}

ConcreteMediator:具體中介者

public class ConcreteMediator : Mediator
{
    // 維持對各個同事物件的引用
    public Button addButton;
    public List list;
    public TextBox userNameTextBox;
    public ComboBox cb;

    // 封裝同事物件之間的互動
    public override void ComponenetChanged(Component c)
    {
        // 單擊按鈕
        if (c == addButton)
        {
            Console.WriteLine("-- 單擊增加按鈕 --");
            list.Update();
            cb.Update();
            userNameTextBox.Update();
        }
        // 從列表框選擇客戶
        else if (c == list)
        {
            Console.WriteLine("-- 從列表框選擇客戶 --");
            cb.Select();
            userNameTextBox.SetText();
        }
        // 從組合框選擇客戶
        else if (c == cb)
        {
            Console.WriteLine("-- 從組合框選擇客戶 --");
            cb.Select();
            userNameTextBox.SetText();
        }
    }
}

Component:抽象元件,充當抽象同事類(Colleague)

public abstract class Component
{
    protected Mediator mediator;

    public void SetMediator(Mediator mediator)
    {
        this.mediator = mediator;
    }

    // 轉發呼叫
    public void Changed()
    {
        mediator.ComponenetChanged(this);
    }

    public abstract void Update();
}

Button、List、ComboBox、TextBox:按鈕、列表框、組合框、文字框,具體元件,充當具體同事類(ConcreteColleague)

public class Button : Component
{
    public override void Update()
    {
        // 按鈕不產生響應
    }
}

public class List : Component
{
    public override void Update()
    {
        Console.WriteLine("列表框增加一項:張無忌");
    }

    public void Select()
    {
        Console.WriteLine("列表框選中項:小龍女");
    }
}

public class ComboBox : Component
{
    public override void Update()
    {
        Console.WriteLine("組合框增加一項:張無忌");
    }

    public void Select()
    {
        Console.WriteLine("組合框選中項:小龍女");
    }
}

public class TextBox : Component
{
    public override void Update()
    {
        Console.WriteLine("客戶資訊增加成功後文字框清空");
    }

    public void SetText()
    {
        Console.WriteLine("文字框顯示:小龍女");
    }
}

Program:客戶端測試類

// Step1.定義中介者物件
ConcreteMediator mediator = new ConcreteMediator();

// Step2.定義同事物件
Button addButton = new Button();
List list = new List();
ComboBox cb = new ComboBox();
TextBox userNameTextBox = new TextBox();

addButton.SetMediator(mediator);
list.SetMediator(mediator);
cb.SetMediator(mediator);
userNameTextBox.SetMediator(mediator);

mediator.addButton = addButton;
mediator.list = list;
mediator.cb = cb;
mediator.userNameTextBox = userNameTextBox;

// Step3.點選增加按鈕
addButton.Changed();

Console.WriteLine("---------------------------------------------");

// Step4.從列表框選擇客戶
list.Changed();
Console.ReadLine();

四、總結

1、優點

(1)中介者模式簡化了物件之間的互動,它用中介者和同事的一對多互動代替了原來同事之間的多對多互動,一對多關係更容易理解、維護和擴充套件,將原本難以理解的網狀結構轉換成相對簡單的星形結構。
(2)可將各同事物件解耦,中介者模式有利於各同事之間的松耦合,可以獨立地改變和複用每一個同事和中介者,增加新的中介者類和新的同事類都比較方便,更好地符合開閉原則。
(3)可以減少子類的生成,中介者模式將原本分佈於多個物件間的行為集中在一起,改變這些行為只需生成新的中介者子類即可,這使得各個同事類可被重用,無須直接對同事類進行擴充套件。

2、缺點

(1)具體中介者子類中包含了大量的同事之間的互動細節,可能會導致具體中介者類非常複雜,使得系統難以維護。

相關文章