`
newleague
  • 浏览: 1499437 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

设计模式系列-适配器模式(&几种模式的链接)

 
阅读更多

一、上篇回顾
        通过上篇的简单讲解,我们知道了,组合模式意图是通过整体与局部之间的关系,通过树形结构的形式进行组织复杂对象,屏蔽对象内部的细节,对

外展现统一的方式来操作对象,是我们处理更复杂对象的一个手段和方式。本文以查询控件为例,说明了,查询控件内部的组成元素,及如何操作内部的组

成元素,包括添加元素,删除和处理相应事件的Handler,当然组合模式的作用远比这些强大,后面我们肯定会在一些实例代码中运用到组合模式的。组合

模式如果在条件允许的情况下,我们尽量使用组合模式来处理复杂对象,远比通过继承出来的对象来的有效。

        组合模式-强调的是如何组织整体和局部之间的结构,将整体和局部之间的关系,通过树形这样的结构来组织这种对象组合的结构关系。

        组合模式的适用场景:

        1、我们期望操作一个复杂对象和操作一个组成这个复杂对象内部的简单对象一样操作的时候,我们可以考虑对象组合。

        2、当一个对象由多个简单对象组成,并且它又可能是其他对象的一个组成部分,这种情况下,组合模式是比较好的选择。

二、摘要
        本篇将会讲述结构型模式中的经典模式-适配器模式,也是项目中经常使用的模式之一,我们现在开发一个系统的时候,也许会遇到各式各样的要求,我们要求和现有的系统

进行集成,或者是我们直接开发一个系统,或者是我们修改已有的系统达到满足现有需求的要求。因此一般来说,每种情况,我们都有自己的应对方案。我们来看看项目中的几种

可能情况:

 

 

通过上面的几种情况,我们知道,开发一个新系统吧,成本和时间的投入较高,如果说我们旧系统目前运行的非常稳定,并且投入的成本非常高,我们既想继续使用旧系统的功

能,又想满足新系统的需求,这个时候,我们怎么做呢?可能比较好的方式就是把旧系统通过适配器来转换成新接口的调用形式,完成适配服务。当然本文也是主要针对这个思

路,展开去讲述适配器模式的一些用法,当然我这里可能讲解了适配器模式的一些普遍用法,还有一些比较特殊的用法,需要大家多多指出,向大伙学习了。

        本文主要讲述下面的几个部分的内容:

        1、适配器模式的使用场景。

        2、适配器模式的经典实现。

        3、多适配器的封装。

        4、其他情况的考虑。

三、本文大纲
       a、上篇回顾。

       b、摘要。

       c、本文大纲。

       d、适配器模式的特点及使用场景。

       e、适配器模式的经典实现。

       f、适配器模式的其他方案。

       g、适配器模式使用总结。

       h、系列进度。

       i、下篇预告。

四、适配器模式的特点及使用场景
         4.1、适配器模式的特点
        适配器模式主要解决的问题就是我们要调用的接口类型,无法满足我们新系统的使用需求,这时候,我们需要将旧系统的接口,通过适配器进行转配,达到支持新接口调用

的目的。对于这样的要求,我们通过适配器就可以完成,当然如果有多个接口需要转配,那么我们就需要为每一个接口提供一个适配器去完成转换的工作。当然具体的调用过程,

我们可以进行相应的封装。达到比较通用的方式去调用适配器,完成适配服务。我们来看看适配的过程。

        上图基本给出了适配器的基本转换的过程。

         4.2、适配器模式的场景
       我们根据上面的适配器的特点的介绍中,我们来分析下适配器模式的几类比较适用的使用场景:

       1、我们在使用第三方的类库,或者说第三方的API的时候,我们通过适配器转换来满足现有系统的使用需求。

       2、我们的旧系统与新系统进行集成的时候,我们发现旧系统的数据无法满足新系统的需求,那么这个时候,我们可能需要适配器,完成调用需求。

       3、我们在使用不同数据库之间进行数据同步。(我这里只是分析的是通过程序来说实现的时候的情况。还有其他的很多种方式[数据库同步])。

五、适配器模式的经典实现
      我们本节给出适配器模式的经典实现代码,我们这里结合项目中的查询服务来进行说明,旧系统中提供一个查询服务方法Query();但是我新系统定义底层的数据访问服务层

的时候,却是使用的GetList()方法,并且将之前的返回结果集合进行包装成泛型的形式来进行。我们这里给出相关的示例代码,大家就能清楚这个使用过程了,当然我们这里给

出类适配器和对象适配器2种实现的方式,通过不同的实现思路,我们最后总结下,这2种形式的优缺点:

   1、类适配器
   针对上面描述的接口的转配过程,我们给出示例代码:

   旧系统的查询服务

    public class Query :IQuery
    {
        public object Query()
        {
            return new object();
        }
    }

新系统的查询服务接口:

    public interface ISelect
    {
        object GetList();
    }

通过类适配器完成转配操作:

    public class QueryAdapter : Query, ISelect
    {
        public object GetList()
        {
            return base.Query();
        }
    }

  具体的调用测试代码如下:

    class Program
    {
        static void Main(string[] args)
        {
            ISelect adapter = new QueryAdapter();

            object o= adapter.GetList();

            System.Threading.Thread.Sleep(10000);

        }
    }

   2、对象适配器
   旧系统的查询服务

    public class Query :IQuery
    {
        public object Query()
        {
            return new object();
        }
    }

新系统的查询服务接口:

    public interface ISelect
    {
        object GetList();
    }

通过类适配器完成转配操作:

    public class QueryAdapter :  ISelect
    {
        private Query query = new Query();

        public object GetList()
        {
            return query.Query();
        }

    }

  具体的调用测试代码如下:

    class Program
    {
        static void Main(string[] args)
        {
            ISelect adapter = new QueryAdapter();

            object o= adapter.GetList();

            System.Threading.Thread.Sleep(10000);

        }
    }

上面我们就完成了经典的适配器模式的简单实现,当然上面也没有考虑通用性等各方面的内容,只是给出了一个大概的实现,当然对于上面的适配器的创建过程,我们可以通过前

面讲述的创建型模式中的几个实现方案,进行相应的改进。

六、适配器模式的其他方案
           上面给出了适配器模式的经典实现,参考其他篇讲述的方式,我们给出适配器模式的其他演变方式

         6.1、批量适配器的封装
        我们在项目中,可能需要对一批的旧系统的接口进行封装,这个时候我们可以通过配置文件的方式配置适配器。

        例如我们上面的查询,可能我现在对于XML文件的查询方法与数据库的查询方法2个旧的查询服务进行封装,然后我在实际的项目中,通过配置来选择我使用哪个查询方法

完成查询服务,通过传入参数,或者是配置节信息来进行控制。我们来看看相关的示例代码:

        旧系统定义的查询服务接口:

    public interface IQuery
    {
        object Query();
    }

        XML查询和数据库方式的实现:

    public class XMLQuery : IQuery
    {
        public object Query()
        {
            throw new NotImplementedException();
        }
    }

    public class DbQuery : IQuery
    {
        public object Query()
        {
            throw new NotImplementedException();
        }
    }

    新查询服务接口:

    public interface ISelect
    {
        object GetList();
    }

    具体的适配器代码实现:

    public class XMLAdapter : ISelect
    {
        private XMLQuery query = new XMLQuery();
        public object GetList()
        {
            return query.Query();
        }
    }

    public class DbAdapter : ISelect
    {
        private DbQuery query = new DbQuery();
        public object GetList()
        {
            return query.Query();
        }
    }

   工厂来负责创建旧系统接口的服务的对象。

    public class AdapterFactory
    {
        public static ISelect CreateAdapter()
        {
            return (ISelect)Activator.CreateInstance(Type.GetType(""));
        }
    }

  具体的调用测试代码:

    class Program
    {
        static void Main(string[] args)
        {
            ISelect select = AdapterFactory.CreateAdapter();

            object o= select.GetList();
        }
    }

         6.2、通用适配器
   旧系统定义的查询服务接口:

    public interface IQuery
    {
        object Query();
    }

        XML查询和数据库方式的实现:

    public class XMLQuery : IQuery
    {
        public object Query()
        {
            throw new NotImplementedException();
        }
    }

    public class DbQuery : IQuery
    {
        public object Query()
        {
            throw new NotImplementedException();
        }
    }

    工厂来负责创建旧系统接口的服务的对象。

    public class OldFactory
    {
         public static IQuery CreateQuery()
         {
             return (IQuery)Activator.CreateInstance(Type.GetType(""));
         }
    }

    新查询服务接口:

    public interface ISelect
    {
        object GetList();
    }

    具体的通用适配器代码实现:

    public class ComAdapter : ISelect
    {
        IQuery query = OldFactory.CreateQuery();

        public object GetList()
        {
            return query.Query();
        }
    }

    将适配器的创建过程通过工厂来实现,达到解耦的目的:

    public class AdapterFactory
    {
        public static ISelect CreateAdapter()
        {
            return new ComAdapter ();

        }
    }

    具体的调用测试代码:

    class Program
    {
        static void Main(string[] args)
        {
            ISelect select = AdapterFactory.CreateAdapter();

            object o= select.GetList();
        }
    }

七、适配器模式使用总结
        我们上面给出了适配器模式的简单讲解,其实适配器模式的应用还是很广泛的,上面也分析了适配器模式的使用场景和特点,那么其实本篇还没有给出实例讲述适配器之间

的转换:        

      上面我们讲述了2中比较通用的形式来调用适配器,还有其他的方式,比如通过字典的方式,然后通过属性索引的形式来使用适配器,我上面给出了一些比较简单的通用的使

用思路,当然还有很多更好的方式,希望大家指出,向大伙学习了。我们这里给出适配器之间相互转换的情况,有的时候,我们发现2个适配器之间也需要进行相应的转配,例如

我们上面的数据库和XML文件的查询接口,例如有的时候,我需要把XML文件的数据转换到数据库中,或者把数据库中的数据保存成XML形式,这个时候,我们就需要定义一个对

象,来完成相应的适配器之间的适配。

通过转配器来完成适配器到适配器之间的转换。具体的代码实现,这里暂不给出

了,下篇会讲桥模式的时候,会给出这部分的具体实现,还请关注!我相信通过上面的讲述,大家对这个适配器模式有了一定的映像,我们上面没有讲述类适配器和对象适配器之

间的区别,这里补充讲解一下:

      对象适配器:不是通过继承的方式,而是通过对象组合的方式来进行处理的,我们只要学过OO的设计原则的都知道,组合相比继承是推荐的方式。

      类适配器:通过继承的方式来实现,将旧系统的方法进行封装。对象适配器在进行适配器之间的转换过程中,无疑类适配器也能完成,但是依赖性会加大,并且随着适配要求的灵活性,可能通过继承膨胀的难以控制。

      一般来说类适配器的灵活性较差,对象适配器较灵活,是我们推荐的方式,可以通过依赖注入的方式,或者是配置的方式来做。类适配器需要继承自要适配的旧系统的类,无疑这不是一个好的办法。

八、系列进度

创建型

        1、系统架构技能之设计模式-单件模式

        2、系统架构技能之设计模式-工厂模式

        3、系统架构技能之设计模式-抽象工厂模式

        4、系统架构技能之设计模式-创建者模式

        5、系统架构技能之设计模式-原型模式

结构型

        1、系统架构技能之设计模式-组合模式

        2、系统架构技能之设计模式-外观模式

        3、系统架构技能之设计模式-适配器模式

        4、系统架构技能之设计模式-桥模式

        5、系统架构技能之设计模式-装饰模式

        6、系统架构技能之设计模式-享元模式

        7、系统架构技能之设计模式-代理模式

行为型

        1、系统架构技能之设计模式-命令模式

        2、系统架构技能之设计模式-观察者模式

        3、系统架构技能之设计模式-策略模式

        4、系统架构技能之设计模式-职责模式

        5、系统架构技能之设计模式-模板模式

        6、系统架构技能之设计模式-中介者模式

        7、系统架构技能之设计模式-解释器模式

九、下篇预告
        下篇,我们将会讲述结构性模式中的桥接模式,我想大家在项目中对桥接模式应该使用的相对来说少一些,我们会结合项目中遇到的一些问题,重构的过程中发现有使用桥接模式,能够更好的解

决依赖的问题。!下篇我们将会进行详细的阐述。

 

本文Demo下载:

http://www.cnblogs.com/hegezhou_hot/archive/2010/12/09/1901040.html

分享到:
评论

相关推荐

    Go设计模式

    Go语言的设计模式可以从以下几个方面来理解: 1. **创建型模式**:这类模式提供了创建对象的最佳方式。Go语言中常见的创建型模式有: - 工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一...

    14.设计模式1

    主要包括以下几种: - 单例模式(Singleton):保证一个类只有一个实例,并提供全局访问点。 - 工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。 - 抽象工厂模式...

    设计模式GOF23(chm格式)

    主要包括以下几种模式: - 单例模式:保证一个类只有一个实例,并提供全局访问点。 - 工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。 - 抽象工厂模式:提供一个创建一系列相关或相互依赖...

    企业应用系统与设计模式.

    设计模式在企业应用系统中的应用广泛,下面列举几种常见的设计模式: 1. **工厂模式**:用于创建对象,隐藏了对象的创建细节,使得代码更易于维护和扩展。在企业系统中,如需生成特定类型的业务对象,工厂模式可以...

    java设计模式-javaDesignPatterns.zip

    Java设计模式是面向对象编程中的一种最佳实践,它是一套被广泛接受并应用于解决常见问题的解决方案模板。这些模式在软件工程中起到了重要的作用,它们是经验丰富的开发者们在面对特定设计挑战时积累的智慧结晶。...

    《设计模式》

    首先,我们来讨论一下标签中提及的几个关键设计模式: 1. **单例模式**:单例模式确保一个类只有一个实例,并提供全局访问点。在Java中,通常通过私有构造函数和静态工厂方法实现。单例模式常用于配置对象、缓存、...

    head frist 设计模式(PDF)-02

    在这些章节中,我们可以预见到以下几个关键的设计模式: 1. **单例模式**:保证一个类只有一个实例,并提供一个全局访问点。这在需要控制资源分配或者需要全局唯一的对象时非常有用。 2. **工厂模式**:定义一个...

    设计模式核心笔录

    在《设计模式核心笔录》中,我们可以期待了解到以下几点关键内容: 1. **设计模式的分类**:设计模式通常被分为创建型、结构型和行为型三大类。创建型模式关注对象的创建,如工厂模式、单例模式和建造者模式等;...

    适配器模式adapter,含源码下载

    适配器模式(Adapter Pattern)是一种结构型设计模式,它能将两个不兼容的接口连接在一起,使得原本由于接口不匹配而无法一起工作的类能够协同工作。在IT行业中,适配器模式广泛应用在系统集成、组件重用以及解决...

    java设计模式及高频面试题

    1. 请解释单例模式的几种实现方式及其优缺点。 2. 举例说明何时会使用工厂模式,以及它与抽象工厂的区别。 3. 请描述代理模式在实际项目中的应用。 4. 解释装饰器模式与继承的关系和区别。 5. 请给出一个适配器模式...

    设计模式与面向对象基本原则(一页纸,打印版)

    文档可能涵盖了以下几种常见的设计模式: 1. 单例模式:确保一个类只有一个实例,并提供全局访问点。 2. 工厂模式:提供创建对象的接口,让子类决定实例化哪个类。 3. 抽象工厂模式:提供创建一系列相关或相互依赖...

    设计模式java源码-design-patterns-java8:演示的源代码

    在这个项目中,你可能会发现以下几种常见的设计模式: 1. **单例模式**:确保一个类只有一个实例,并提供全局访问点。在Java 8中,可以使用静态内部类或双检锁/双重校验锁(DCL)来实现单例。 2. **工厂模式**:...

    design_pattern:几种设计模式的实现

    设计模式如果要执行任何提供的测试程序,请查看模式文件夹中的 README.md。 要启动各种测试程序,请阅读 README.md 文件中每个文件夹中的说明抽象工厂提供一个接口来创建属于同一系列的对象组。 提供用于从同一族...

    适用于 MATLAB 的数据转换 DAQ 适配器.pdf

    适用于MATLAB的数据转换DAQ适配器为研究人员和工程师提供了一种强大而灵活的工具,使得他们在MATLAB环境中能够轻松实现数据采集与分析。通过深入了解本手册中介绍的各项功能和特性,用户不仅能够充分利用该设备完成...

    design_model:设计模式的相关学习(基于Java)

    设计模式是软件工程中的一种最佳实践,它是在特定上下文中解决常见问题的模板,为软件设计提供了一套标准的解决方案。在Java编程中,设计模式的重要性不言而喻,它们帮助开发者编写可维护、可扩展且高效的应用程序。...

    装饰者模式

    装饰者模式是一种设计模式,它允许我们向一个对象动态地添加新的行为或责任,而无需修改该对象的源代码。这种模式遵循“开闭原则”,即对扩展开放,对修改关闭,是面向对象设计中非常重要的一个概念。装饰者模式通常...

    C8051F工具及应用 c8051系列工具 c8051系列工具说明

    U-EC5提供了多种调试接口选项,包括JTAG模式和C2模式,这两种模式都允许开发者进行代码的上传和调试,但具体的应用场景有所不同。此外,U-EC5还支持多种操作系统,确保了广泛的兼容性和便捷性。通过即插即用的设计,...

    headfirst JAVA实现

    以下是几个关键的设计模式和Java编程知识点: 1. **单例模式**:保证一个类只有一个实例,并提供一个全局访问点。在Java中,可以使用私有构造函数和静态工厂方法或者双重检查锁定(Double-Checked Locking)来实现...

Global site tag (gtag.js) - Google Analytics