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模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。
    类适配器采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用。对象适配器采用“对象组合”的方式,符合松耦合。
  • 相关阅读:
    matplotlib 进阶之origin and extent in imshow
    Momentum and NAG
    matplotlib 进阶之Tight Layout guide
    matplotlib 进阶之Constrained Layout Guide
    matplotlib 进阶之Customizing Figure Layouts Using GridSpec and Other Functions
    matplotlb 进阶之Styling with cycler
    matplotlib 进阶之Legend guide
    Django Admin Cookbook-10如何启用对计算字段的过滤
    Django Admin Cookbook-9如何启用对计算字段的排序
    Django Admin Cookbook-8如何在Django admin中优化查询
  • 原文地址:https://www.cnblogs.com/ejiyuan/p/2570298.html
Copyright © 2011-2022 走看看