中介模式定义了一个单独的中介对象,来封装一组对象之间的交互。将这组对象之间的交互委派给与中介对象交互,来避免对象之间的直接交互。
结构图:
角色:
- 抽象中介者(Mediator):接口声明了与组件交流的方法,但通常仅包括一个通知方法。
- 具体中介者(Concrete Mediator):封装了多种组件间的关系。 具体中介者通常会保存所有组件的引用并对其进行管理。
- 抽象组件(Component):声明所有组件公共方法和属性。
- 具体组件(Concrete Colleague):包含业务逻辑的类,每个组件都有一个指向中介者的引用的接口类型,组件不知道中介者实际所属的类, 因此可通过将其连接到不同的中介者以使其能在其他程序中复用。
适用场景:
- 对象和其他对象紧密耦合度过高时。
优点:
- 通过增加中介者可以有效的解决类耦合度过高的问题。
缺点:
- 中介类过于臃肿,最终可能会演化成上帝类。
代码(C#)
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
public interface IMediator { void Notify(BaseComponent sender, string ev); }
public class ConcreteMediator : IMediator { private Component1 _component1;
private Component2 _component2;
public ConcreteMediator(Component1 component1, Component2 component2) { _component2 = component2; _component1 = component1;
_component1.SetMediator(this); _component2.SetMediator(this); }
public void Notify(BaseComponent sender, string ev) { if (ev == "A") { _component2.DoC(); }
if (ev == "D") { _component1.DoB(); _component2.DoC(); } } }
public class BaseComponent { protected IMediator? _mediator;
public BaseComponent(IMediator? mediator = null) { _mediator = mediator; }
public void SetMediator(IMediator? mediator) { _mediator = mediator; } }
public class Component1 : BaseComponent { public void DoA() { Console.WriteLine("Component 1 does A.");
_mediator?.Notify(this, "A"); }
public void DoB() { Console.WriteLine("Component 1 does B."); _mediator?.Notify(this, "B"); } }
public class Component2 : BaseComponent { public void DoC() { Console.WriteLine("Component 2 does C.");
_mediator?.Notify(this, "C"); }
public void DoD() { Console.WriteLine("Component 2 does D.");
_mediator?.Notify(this, "D"); } }
Component1 component1 = new Component1(); Component2 component2 = new Component2(); IMediator mediator = new ConcreteMediator(component1, component2);
Console.WriteLine("触发A操作"); component1.DoA();
Console.WriteLine();
Console.WriteLine("触发D操作"); component2.DoD();
|
最后
中介模式的设计思想跟中间层很像,通过引入中介这个中间层,将一组对象之间的交互关系(或者依赖关系)从多对多(网状关系)转换为一对多(星状关系)。原来一个对象要跟 n 个对象交互,现在只需要跟一个中介对象交互,从而最小化对象之间的交互关系,降低了代码的复杂度,提高了代码的可读性和可维护性。