北川广海の梦

北川广海の梦

设计模式:中介者模式与桥接模式

2021-11-11

中介者模式

在一个包含UI的客户端程序中,我们通常会包含许多UI组件,这些组件之间常常会有复杂的逻辑交互。例如一些按钮联动等等。如果我们在每一个组件中都需要处理其他按钮发生的事情,那么每一个组件都会变得极不稳定且难以维护。

想象一下机场塔台,它负责一切航班之间的调度。航班之间互相无需关心彼此的存在。类似的,我们可以采用这样的模式解决组件之间的相互依赖关系。

通过中介者模式,构建一个中介者对象,屏蔽组件之间的通讯,让他们只能通过中介者来交流。中介者来负责所有的细节。

  public interface IComponent : IEqualityComparer<IComponent>
    {
        public IMediator Mediator { get; set; }
        
        public string Id { get; set; }
        
        public string ComponentType { get; set; }
    }

    public interface IMediator
    {
        public void Notify(IComponent sender);

        public bool RegisterComponent(IComponent component);
    }

    public class UserInterfaceMediator : IMediator
    {
        public readonly HashSet<IComponent> Components = new HashSet<IComponent>();

        public void Notify(IComponent sender)
        {
            if (Components.TryGetValue(sender, out sender))
            {
                ReactSender(sender);
            }
        }

        public bool RegisterComponent(IComponent component)
        {
            return Components.Add(component);
        }

        protected virtual void ReactSender(IComponent sender)
        {
        }
    }

中介者模式与观察者模式很像,但是中介者模式主要是为了消除组件之间的耦合依赖。而观察者模式是为了建议组件的单向通讯。观察者模式是没有中心的,而中介者模式中,中介者对象本身就是一个中心。

桥接模式

在语言的继承中,我们面临竖向层次的扩展,通常非常简单。例如车->汽车->宝马车这样一条。我们也能很容易的继承于其中某一个类。但是加入我们现在的扩展需求是横向的呢?现在宝马车变成了红色的宝马和白色的宝马。我们还是需要增加一个类吗?在这个时候,我们考虑的肯定是以车的种类为继承链,而车的某些属性,应该通过组合的方式放入类中。

    public interface IRemote
    {
        public IDevice Device { get; set; }

        public void BindDevice(IDevice device);
        
        public void Next();
        public void Last();
        public void Open();
        public void Close();
    }

    public interface IDevice
    {
        public void OnNext();
        public void OnLast();
        public void OnOpen();
        public void OnClose();
    }

    public class TelevisionA : IDevice
    {
        public void OnNext()
        {
        }

        public void OnLast()
        {
        }

        public void OnOpen()
        {
        }

        public void OnClose()
        {
        }
    }

    public class TelevisionB : IDevice
    {
        public void OnNext()
        {
        }

        public void OnLast()
        {
        }

        public void OnOpen()
        {
        }

        public void OnClose()
        {
        }
    }

遥控器与设备,被分别高度抽象为两个接口。现在假设我们有上千种不同的设备,但是它们任然可以用一个遥控器完成控制。因为设备类只依赖的是抽象。桥接模式指的并不是类与类之间的桥接。而是抽象与实现之间的桥接。当一个类依赖另一个类的时候,不直接依赖这个类,而是依赖这个类的抽象,而这个类具体实现与这个类的抽象之间,就是一种桥接关系。