温故而知新:设计模式之适配器模式(Adapter)

借用terrylee的原话:

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

适配器模式再次体现了“面向接口编程,而非面向实现编程”这一精神。

场景:

有一个基于数据库的系统,里面的数据库操作就拿最常用的查询来说,主要是用SqlHelper类里的QueryData(string sql)这个方法来处理的,后来意外发现该方法实现上性能并不是最好(或者不能满足新的需要),而这时正好有一个第三方的DbHelper程序集,写得很成熟性能也不错,但唯一不足的是里面的查询方法签名是SelectData(string sql),怎么办?所有引用SqlHelper的地方全部修改,重头编译么?No,没人会想这样

先看下原来的代码:

using System;
using System.Data;

namespace Adapter
{
    class Program
    {
        static void Main(string[] args)
        {
            IDBHelper dbhelper = new SqlHelper();
            dbhelper.QueryData("Select * from TableA");

            Console.ReadKey();
        }
    }

    public interface IDBHelper 
    {
        DataSet QueryData(string sql);
    }

    public class SqlHelper : IDBHelper 
    {
        public DataSet QueryData(string sql) 
        {
            Console.WriteLine("QueryData is Called,the sql is :\"{0}\"",sql);
            return new DataSet();//这里演示起见,就直接返回一个DataSet实例完事 :)
        }
    }
}

 

如何在尽量不影响原有客户端代码的情况下,用新的DbHelper来取代旧的SqlHelper呢?

假如第三方的DBHelper结构如下:

 

/// <summary>
    /// 第三方的新dbHelper,实际场景中,这个类通常都是封装在程序集中以dll提供,客户端程序无法修改
    /// </summary>
    public class DbHelper 
    {
        public DataSet SelectData(string sql)
        {
            Console.WriteLine("SelectData is Called,the sql is :\"{0}\"", sql);
            return new DataSet();//这里演示起见,就直接返回一个DataSet实例完事 :)
        }
    }

 

可以新增一个适配器:

    /// <summary>
    /// 新增的适配器
    /// </summary>
    public class DBHelperAdapter : IDBHelper 
    {
        private DbHelper _dbHelper;

        public DBHelperAdapter(DbHelper dbHelper) 
        {
            this._dbHelper = dbHelper;
        }

        public DataSet QueryData(string sql)         
        {
            return _dbHelper.SelectData(sql);
        }

    }

 

这样原有的客户端程序,只需要把
IDBHelper dbhelper = new SqlHelper();

改成:

IDBHelper dbhelper = new DBHelperAdapter(new DbHelper()); 就万事大吉了,当然你可以用配置文件+反射,完全解耦,此处略过

反思:

本例中之所以能轻易将新的类替换旧的类,主要得益于旧的代码仅依赖于抽象(即接口IDBHelper),而非具体的实现(即类SqlHelper),否则也不可能达到最终效果。

OO原则中的"面对接口编码","依赖倒置"的妙处也就在于此。

 

最后给出类图:

时间: 2024-08-01 01:41:41

温故而知新:设计模式之适配器模式(Adapter)的相关文章

乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)

原文:乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)[索引页][源码下载] 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) 作者:webabcd 介绍 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 示例 有一个Message实体类,某个类对它的操作有Insert()和Get()方法.现在需要把这个类转到另一个接口,分别对应Add()和Select()方法. Mess

【设计模式】—— 适配器模式Adapter

模式意图 如果已经有了一种类,而需要调用的接口却并不能通过这个类实现.因此,把这个现有的类,经过适配,转换成支持接口的类. 换句话说,就是把一种现有的接口编程另一种可用的接口. 模式结构 [类的适配器] Target 目标接口 Adaptee 现有的类 Adapter 中间转换的类,即实现了目标接口,又继承了现有的类. 1 package com.xingoo.test1; 2 interface Target{ 3 public void operation1(); 4 public void

设计模式(五)适配器模式Adapter(结构型)

设计模式(五)适配器模式Adapter(结构型) 1. 概述:          接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题.程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相关库的发展和进化.         例子1:iphone4,你即可以使用UBS接口连接电脑来充电,假如只有iphone没有电脑,怎么办呢?苹果提供了iphone电源适配器.可以使用这个电源适配器充电.这个iphone的电源适配器就是类似我们说的适配器模式.(电源适配器就是把电源变成需要

C#设计模式(7)——适配器模式(Adapter Pattern)

原文:C#设计模式(7)--适配器模式(Adapter Pattern) 一.引言 在实际的开发过程中,由于应用环境的变化(例如使用语言的变化),我们需要的实现在新的环境中没有现存对象可以满足,但是其他环境却存在这样现存的对象.那么如果将"将现存的对象"在新的环境中进行调用呢?解决这个问题的办法就是我们本文要介绍的适配器模式--使得新环境中不需要去重复实现已经存在了的实现而很好地把现有对象(指原来环境中的现有对象)加入到新环境来使用. 二.适配器模式的详细介绍 2.1 定义  下面让我

PHP设计模式之适配器模式代码实例

  这篇文章主要介绍了PHP设计模式之适配器模式代码实例,本文讲解了目标.角色.应用场景.优势等内容,并给出代码实例,需要的朋友可以参考下 目标: 可将一个类的接口转换成客户希望的另外一个接口,使得原本不兼容的接口能够一起工作.通俗的理解就是将不同接口适配成统一的API接口. 角色: Target适配目标,该角色定义把其他类转换为何种接口,也就是我们的期望接口. Adaptee被适配者,就是需要被适配的接口. Adapter适配器,其他的两个角色都是已经存在的角色,而适配器角色是需要新建立的,它

设计模式之适配器模式

设计模式目录 http://blog.csdn.net/fenglailea/article/details/52733435 风.fox 适配器模式 Adapter Pattern 也叫做变压器模式,也叫包装模式 将一个类的接口变换成客户端所期待的另一个接口,从而使原本接口不匹配而无法再一起工作的两个类能够在一起工作 通用类图 组成 目标角色 定义把其他类转换为何种接口,也就是我们的期望接口 源角色 你想把谁转换成目标角色 适配器角色 把源角色转换为目标角色 通用源码 JAVA //目标角色

解读设计模式----适配器模式(Adapter Pattern)

在金庸笔下,三大神功都是难得之宝,多少人为得到他而......,仔细的分析下这三大神功,还是北冥较好,呵呵.我们从软件设计的角度来看,这不知算不算得上是一种复用(功力复用)的思想,只不过有点残忍罢.而在软件设计领域里,"复用"在某些时候也会出现很多问题,比如平台不兼容,开发语言不同或是接口不同等多种原因,弄得不好会不会出现既浪费了别人的现有资源,而自己的系统又无法完成呢?这有点像吸星----损人又损己. 企图将设计做好,就能够一劳永逸地坐享其成,这样的愿望就好上面所提到的吸星神功一般,

设计模式:适配器模式(Adapter)

 适配器模式:将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.  适配器模式有类适配器模式和对象适配器模式两种不同的形式. 类适配器  类适配器模式把适配的类的API转换成目标类的API  适配器模式所涉及的角色: 目标角色(Target): 这就是所期待得到的接口. 源角色(Adaptee):需要适配的接口 适配器角色(Adapter):适配器类是本模式的核心.适配器把源接口转换成目标接口.显然,这一角色不可以是接口,而必须是具体

Java设计模式之适配器模式(Adapter模式)介绍_java

适配器模式定义:将两个不兼容的类纠合在一起使用,属于结构型模式,需要有Adaptee(被适配者)和Adaptor(适配器)两个身份. 为何使用适配器模式 我们经常碰到要将两个没有关系的类组合在一起使用,第一解决方案是:修改各自类的接口,但是如果我们没有源代码,或者,我们不愿意为了一个应用而修改各自的接口. 怎么办? 使用Adapter,在这两种接口之间创建一个混合接口(混血儿). 如何使用适配器模式 实现Adapter方式,其实"think in Java"的"类再生&quo