zoukankan      html  css  js  c++  java
  • 设计模式学习总结适配器模式(Adapter Pattern)

    问题:
    在面向对象的软件设计中,经常需要将一些现存的对象放在新的环境中或与新的对象一起工作,但是他的接口与新环境要求的接口不同,而双方又都无法改变。
    定义:
    适配器模式 也称包装样式或者包装,将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
    意图:
    定义一个Adapter角色,将一个已存在的Adaptee类,通过继承或包装的手段,让他与现有的类实现同一接口的办法,转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
    参与者:
    •目标(Target)角色:
    这是客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
    •源(Adaptee)角色:
    需要适配的类。
    •适配器(Adapter)角色:
    通过在继承或内部包装(Wrap)一个Adaptee对象,把源接口转换成目标接口。此角色要继承Target。

    分类
    适配器模式的变化比较多,可以通过继承和组合方式进行适配,适配器可以是一组适配器产品,适配器也可以是抽象类型。
    •类适配器:
    提供一个实现该接口的类,并且扩展已有的类,通过创建子类来实现适配。


    •对象适配器:
    对象适配器”通过组合除了满足“用户期待接口”还降低了代码间的不良耦合。

    实例说明:

    诺基亚手机工厂
    生产工厂 有两个生产车间,生产方式有所不同,下面例子通过 对象适配器 适配生产车间1,通过类适配器适配生产车间2,让他们有一个共同的面向客户的接口。

    uml图如下:

     

    代码:

    /// <summary>
    /// N8手机抽象产品类,目标(Target)角色,客户端调用接口
    /// </summary>
    public interface IPhoneFactory
    {
        void Create(string Name, int Count);
    }

    /// <summary>
    /// 一号生产车间 Adaptee 角色
    /// </summary>
    public class PhoneFactory1
    {
        public int Count { getset; }

        public void Create(string Name)
        {
            System.Console.WriteLine("生产{0}个{1}手机"this.Count, Name);
        }
    }
    /// <summary>
    /// 二号生产车间 Adaptee 角色
    /// </summary>
    public class PhoneFactory2
    {
        public void Build(string Name, int Count)
        {
            System.Console.WriteLine("生产{0}个{1}手机", Count, Name);
        }
    }
    /// <summary>
    /// 适配器1用于适配一号生产车间,通过在内部包装(Wrap)一个Adaptee对象,把源接口转换成目标接口。
    /// </summary>
    public class FactoryAdapter1 : IPhoneFactory
    {
        PhoneFactory1 phoneFactory1 = new PhoneFactory1();

        public void Create(string Name, int Count)
        {
            phoneFactory1.Count = Count;
            phoneFactory1.Create(Name);
        }
    }
    /// <summary>
    /// 适配器2 用于适配二号生产车间,通过在继承一个Adaptee对象,把源接口转换成目标接口。
    /// </summary>
    public class FactoryAdapter2 : PhoneFactory2, IPhoneFactory
    {
        public void Create(string Name, int Count)
        {
            base.Build(Name, Count);
        }
    }
    /// <summary>
    /// 客户端测试
    /// </summary>
    public void AdapterTest()
    {
        IPhoneFactory pf = new FactoryAdapter1();
        pf.Create("N8"10);

        pf = new FactoryAdapter2();
        pf.Create("N8"10);
    }

    优点:
    •对代码复用、类库迁移等方面的实现变得非常容易。
    •类适配器因为Adapter是Adaptee的一个子类所以可以通过重写重新定义Adaptee的部分行为。
    •对象适配器允许一个Adapter与多个Adaptee,即Adaptee本身以及它的所有子类一起工作。

    缺点:

    •需要改变(适配)多个已有子类的接口,如果使用类的适配器模式,就要针对每个类做一个适配器。
    •类适配器使用了“多继承”的实现方式,带来了不良的高耦合。

    应用情景:

    •系统需要使用现有的类,而此类的接口不符合系统的需要。

    •想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
    PS:

    适配器模式是否能成功运用的关键在于代码本身是否是基于接口编程的,如果不是的话,那么适配器无能为力。

    Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。

    Adapter模式的实现可以非常。处了类适配器和对象适配器,还可以将Adapter模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。
    类适配器采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用。对象适配器采用“对象组合”的方式,符合松耦合。
  • 相关阅读:
    9.类与对象二----重载、值传递、可变个数形参
    1.数据库相关概念
    8.类与对象一举例
    7.类与对象一
    Educational Codeforces Round 91 (Rated for Div. 2) B. Universal Solution(思维)
    VS Code配置C++环境: Unable to start debugging. Unexpected GDB output from command报错
    Codeforces Round #655 (Div. 2) C. Omkar and Baseball(思维)
    Redis高可用,高性能,高并发
    .Net Core 中GC的工作原理
    大数据环境下该如何优雅地设计数据分层
  • 原文地址:https://www.cnblogs.com/ejiyuan/p/2570298.html
Copyright © 2011-2022 走看看