MediatorPattern(中介者模式)

說明

系統模塊存在很多複雜的耦合問題,很適合使用中介者模式來解耦合

在現實中如果組織有一定規模可能構通如下圖那般複雜

如果有一個人或組織負責幫大家協助溝通,就可解決上面複雜問題

這就是我們這次的核心中介者

中介者模式有幾個角色

  • AbstractMediator (抽像中介者):定義中介者和各個同事者之間的通信的介面
  • ConcreteMediator (中介者):知道每個同事物件,實現抽像中介者,負責協調和各個具體的同事的交互關係
  • AbstractColleague (抽象同事者):定義同事者和中介者通信的接口
  • ConcreteColleague (同事者):實現自己的業務,並且實現抽象方法,跟中介者進行通信

中介者模式特點是

  • 中介者知道所有同事者物件,但同事者互相不知道對方存在需透過中介者傳遞訊息
  • 如何傳遞和通知各個同事者由中介者內部決定

在裡面第二點是很重要的目標,把傳遞訊息的邏輯封裝在中介者裡面

程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ProductManager
{
public DBAdmin DbAdmin { get; set; }
public Programer Programer { get; set; }

internal void Send(string message, OriginReqBase req)
{
       //如果是DBAdmin傳遞訊息由Programer執行,反之
if (req.GetType() == typeof(DBAdmin))
Programer.DoProcess(message);
else if(req.GetType() == typeof(Programer))
DbAdmin.DoProcess(message);
}
}

傳遞通知或訊息邏輯寫在Send方法裡面.

本次範例依照傳入的型別,如果是DBAdmin傳遞訊息由Programer執行,反之

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public abstract class OriginReqBase
{
protected ProductManager _productManager;

protected OriginReqBase(ProductManager productManager)
{
_productManager = productManager;
}

public virtual void Requirement(string message)
{
_productManager.Send(message, this);
}
}

OriginReqBase(抽象同事者) 因為每個角色 (ConcreteColleague) 都需要知道中介者存在,所以把參數設定在建構子上。

Requirement方法通知 PM 中介者將資料傳遞出去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Programer : OriginReqBase
{

public void DoProcess(string message)
{
Console.WriteLine($"Programer: {message}");
}

public Programer(ProductManager productManager) : base(productManager)
{
}
}

public class DBAdmin : OriginReqBase
{

public void DoProcess(string message)
{
Console.WriteLine($"DBA:{message}");
}

public DBAdmin(ProductManager productManager) : base(productManager)
{
}
}

DoProcess 方法 PM 中介者呼叫使用

1
2
3
4
5
6
7
8
9
10
11
ProductManager pm = new ProductManager();

DBAdmin DBA1 = new DBAdmin(pm); //DBA知道PM存在
Programer RD1 = new Programer(pm); //RD知道PM存在

pm.Programer = RD1; //PM知道DBA
pm.DbAdmin = DBA1; //PM知道RD

//現在DBA和RD只需要傳訊息就可將訊息轉到需要知道的人
RD1.Requirement("DB modify Requestment.");
DBA1.Requirement("DB Process doing.");

有三大重點

  1. DBA和RD(同事者) 知道PM(中介者)存在
  2. PM(中介者)知道DBA和RD(同事者)存在
  3. ㄋDBA和RD不用知道對方存在但卻可以互相傳遞訊息(因為PM已經幫助我們解耦合了)

UML圖 (有標示相對應的角色關係)

我看來這個解耦合核心思想跟容器有點像,因為需要做溝通或通知時我們統一只需要轉交給中介者會幫助我們處理溝通事宜

此文作者:Daniel Shih(石頭)
此文地址https://isdaniel.github.io/mediator-pattern/
版權聲明:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!


如果本文對您幫助很大,可街口支付斗內鼓勵石頭^^