設計模式(18) 中介者模式
阿新 • • 發佈:2020-08-24
一個軟體系統中往往包含了很多的類,這些類之間會存在互相的呼叫,隨著系統的升級、功能的擴充套件,這些相互呼叫關係會變得非常複雜,,大量的相互連線使得這樣一個型別系統不太可能在沒有其他類支援的情況下獨立完成工作,久而久之這些類將變得像一個不可分割的整體,內部有著錯綜複雜的關聯。這會導致後期維護特別困難,對系統或模組的任何較大的變動都可能造成無法預知的問題。
中介者模式
中介者模式可以解決這種問題。它通過提供一箇中介類,來處理不同類之間的通訊,這樣可以降低多個類之間的通訊複雜度,使程式碼更易於維護。中介者模式屬於行為型模式。通過應用Mediator模式,可以將類與類之間的多對多的關係轉化成一對多的關係,從而降低了類之間的耦合。
GOF對中介者模式描述為:
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently..
— Design Patterns : Elements of Reusable Object-Oriented Software
UML類圖:
程式碼實現
public interface IMediator<T> { void Operation(); void Register(IColleague<T> provider, params IColleague<T>[] consumers); } public interface IColleague<T> { T Data { get; set; } IMediator<T> Mediator { get; set; } } public abstract class ColleagueBase<T> : IColleague<T> { public virtual T Data { get; set; } private IMediator<T> mediator; public virtual IMediator<T> Mediator { get { return mediator; } set { mediator = value; } } } public class Mediator<T> : IMediator<T> { private IColleague<T> provider; private IList<IColleague<T>> consumers; public void Operation() { if (provider != null && consumers != null && consumers.Count > 0) { foreach (var item in consumers) { item.Data = provider.Data; } } } public void Register(IColleague<T> provider, params IColleague<T>[] consumers) { this.provider = provider; if (consumers != null && consumers.Length > 0) { this.consumers = new List<IColleague<T>>(consumers); } } } public class ConcreteColleagueA : ColleagueBase<int> { public override int Data { get => base.Data; set { base.Data = value; base.Mediator.Operation(); } } } public class ConcreteColleagueB : ColleagueBase<int> { } public class ConcreteColleagueC : ColleagueBase<int> { }
呼叫端:
public class Test
{
public static void Entry()
{
Mediator<int> mA2BC = new Mediator<int>();
ConcreteColleagueA a = new ConcreteColleagueA();
ConcreteColleagueB b = new ConcreteColleagueB();
ConcreteColleagueC c = new ConcreteColleagueC();
a.Mediator = b.Mediator = c.Mediator = mA2BC;
mA2BC.Register(a, b, c);
a.Data = 20;
Console.WriteLine($"a:{a.Data},b:{b.Data}, c:{c.Data}"); //a:20,b:20,c:20
mA2BC.Register(a, b);
a.Data = 30;
Console.WriteLine($"a:{a.Data},b:{b.Data}, c:{c.Data}"); //a:30,b:30,c:20
}
}
適用場景
- 系統中物件之間存在比較複雜的引用關係,導致他們之間的依賴關係結構混亂而且難以複用該物件。
- 想通過一箇中間類來封裝多個類中的行為,而又不想生成太多的子類。
優缺點
優點
- 降低了系統類的複雜度,將一對多轉化成了一對一,只需要與中介者互動
- 中介者模式使得物件之間不需要顯式地相互引用,從而使得系統或模組內部相互解耦。
- 符合迪米特原則
缺點
由於中介者物件封裝了各個類之間的互動,會導致中介者類本身的複雜性上升,會有一定的維護成本
參考書籍:
王翔著 《設計模式——基於C#的工程化實現及擴充套件》