行为型设计模式。
在QQ的聊天中,存在两种聊天方式,一种是两个用户之间直接进行聊天,另一种是将所有相关用户放在一个QQ群中,我们在群中聊天。在QQ聊天软件中,用户与用户之间的关系存在多对多的关系,这导致系统中用户之间的关系形成了复杂的关系网,如果没有QQ群,一个用户想要将相同的信息发送给其他用户就需要一个一个的发,但如果我们将所有需要接收这条信息的用户拉到一个QQ群中,用户只需要和QQ群一个对象交互即可。群会将发送者的发送的信息转发给每一个接收者。,通过引入QQ群,将极大地减少系统中用户之间的两两通讯。
在软件开发中,如果每些类或者对象之间相互调用的关系错综复杂,类似QQ中用户之间的关系,我们就可以引入一个类似QQ群的中间类来协调这些类或者对象,以降低系统的耦合度。中介者模式为此诞生。通过引入中介者,原本的对象之间的多对多的关系将可以简化为一对多的关系。
中介者模式常用于简化同一类对象之间的调用关系,所以中介者模式将可以为本类的各个对象提供一个中转作用,对象将不需要显式引用其他同事类,只需要通过中介者就可以找到。中介者模式可以为一个类的所有对象提供集中管理的功能,简单来说中介者就是这些对象的一个管理类,这一点导致中介者模式的模式类图与享元模式在结构上几乎是一样的。
经典中介者模式有以下4个角色构成:
Mediator(抽象中介者):
它定义了一个接口,该接口用于与各同事对象之间进行通讯。
ConcreteMediator(具体中介者):
抽象中介者的子类,通过协调各个同事对象来实现协作行为,维持了对各个同事对象的引用。
Colleague(抽象同事类):
它定义了个各同事类对象的共有方法,同时维持一个对抽象中介者类的引用,其子类可以通过该引用与中介者通讯。
ConcreteColleague(具体同事类):
他是抽象同事类的子类,在具体同事类中实现了抽象同事类中的抽象方法。
例子:某软件公司要开发一套CRM系统,其中包含一个客户信息管理模块,通过分析发现,界面组件之间存在着较为复杂的交互关系:如果删除一个客户,将从客户列表(List)中删除对应的项。尝试使用中介者模式模拟该系统。
抽象中介者类:
using System.Collections.Generic;
namespace Mediator.Mediator.Example
{
public abstract class Mediator
{
private Dictionary<string, Component> _dictionary = new Dictionary<string, Component>();
public void Register(string name, Component component)
{
var hashCode = component.GetHashCode();
_dictionary.Add(name, component);
}
public void Remove(string name, Component component)
{
_dictionary.Remove(name);
}
public Component Find(string name)
{
return _dictionary[name];
}
public abstract void Execute(Component component);
}
}
抽象组件类:
namespace Mediator.Mediator.Example
{
public abstract class Component
{
public const string NAME = "";
private Example.Mediator _mediator;
public void SetMediator(Example.Mediator mediator)
{
_mediator = mediator;
}
public void Execute()
{
_mediator.Execute(this);
}
public abstract void Update();
}
}
具体中介者类:
using System.Collections.Generic;
namespace Mediator.Mediator.Example
{
public class ConcreteMediator : Mediator
{
//按钮和列表的调用关系
public override void Execute(Component component)
{
if (component is Button)
{
Find(List.NAME).Update();
}
else if(component is List)
{
Find(Button.NAME).Update();
}
}
}
}
按钮类:
using System;
namespace Mediator.Mediator.Example
{
public class Button : Component
{
public new const string NAME = "Button";
public override void Update()
{
Console.WriteLine($"按钮更新");
}
}
}
列表类:
using System;
namespace Mediator.Mediator.Example
{
public class List : Component
{
public new const string NAME = "List";
public override void Update()
{
Console.WriteLine($"列表更新");
}
}
}
Program类:
using Mediator.Mediator.Example;
using Mediator.Mediator.Question5;
using Mediator.Mediator.Question5.MyCommand;
using Mediator.Mediator.Question5.MyPane;
namespace Mediator
{
internal class Program
{
public static void Main(string[] args)
{
Mediator.Example.Mediator mediator = new ConcreteMediator();
Component button = new Button();
mediator.Register(Button.NAME,button);
Component list = new List();
mediator.Register(List.NAME,list);
//这里由于在中介者中设置的原因,button执行会同时执行list中的update
button.SetMediator(mediator);
button.Execute();
//这里由于在中介者中设置的原因,list执行会同时执行button中的update
list.SetMediator(mediator);
list.Execute();
}
}
}