C#设计模式之7:适配器模式

vczh的日常 2018-04-08

适配器模式

使用适配器模式的一个重要的点是首先要识别出什么代码(接口)是已经存在的,什么代码(接口)是新的,需要去适配的。适配器的作用是让旧的(现有的)接口能够匹配新的系统(要去适配的)。

比如有下面两个接口,一个是系统已经有的:

public interface IDuck
{
void Quack();
void Fly();
}

鸭子接口是系统已经有的,我们现在要开发一套针对火鸡的,火鸡的接口是这样的:

public interface ITurkey
    {
        void Gobble();
        void Fly();
    }

我们要用这个火鸡去做一些事情,如果直接用的话火鸡和现有的鸭子接口是不匹配的,我们不能在需要一个鸭子的地方放进去一个实例化的火鸡。系统会报错。。。

那么我们现在要做的就是这样:

public class DuckAdapter:IDuck
    {
        private ITurkey _turkey;

        public DuckAdapter(ITurkey turkey)
        {
            _turkey = turkey;
        }
        public void Quack()
        {
           _turkey.Gobble();
        }

        public void Fly()
        {
           _turkey.Fly();
        }
    }

我们要给鸭子做一个适配器,这个适配器根据控制反转的原则,不依赖具体实现,依赖的是抽象的ITurkey(作为这个类的私有成员),然后在运行时动态的传入(DI)一个ITurkey的实例。

DuckAdapter实现了IDuck的接口,这样就实现了和原有系统的类型一致性,然后再利用对象组合的的方式(这个满足多用组合,少用继承的面向对象设计原则)对火鸡的成员进行调用。

下面用一个接插头来比喻这件事情:

C#设计模式之7:适配器模式

上图中,ITurkey就是一个客户,而IDuck是一个被适配者,对于整个系统而言,IDuck是旧系统,是已经存在的系统,我们要将ITurkey适配到已有系统上面,直接搞是不行的,需要有一个中间的“适配器”来做适配。这个适配器就是上述代码中的DuckAdapter类。

如果不用适配器,就得改写客户端的代码来对新的接口(ITurkey接口)进行合适的调用。将会花费大量的精力来对调查和改写代码。相比之下,提供一个适配器,将所有的改变封装在一个类中,是比较好的做法。

适配器的工作是将一个接口转换成另一个,但是我们的世界实在是太复杂了,有的时候需要使用一个新的适配器来包装多个被适配者。

还有一种是双向适配器,可以用实现多个接口的方式来达成这个目标,这里的多个接口指得是新的接口和旧的接口都实现。

下面给出适配器模式的定义:将一个类的接口,转换成客户期望的另一个接口,适配器让原本接口不相容的类型合作无间。

C#设计模式之7:适配器模式

与适配器模式类似的是外观模式,请看下一章。

相关推荐