前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >温故而知新:设计模式之适配器模式(Adapter)

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

作者头像
菩提树下的杨过
发布2018-01-22 16:17:02
6000
发布2018-01-22 16:17:02
举报

借用terrylee的原话:

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

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

场景:

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

先看下原来的代码:

代码语言:js
复制
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结构如下:

代码语言:js
复制
/// <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实例完事 :)
        }
    }

可以新增一个适配器:

代码语言:js
复制
 /// <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原则中的"面对接口编码","依赖倒置"的妙处也就在于此。

最后给出类图:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2010-01-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档