什么是适配器模式?

适配器模式是一种结构型设计模式,用于将现有接口转换为符合客户端期望的接口。适配器模式允许不兼容的类可以相互协作。

为什么需要适配器模式?

在实际开发中,经常会遇到需要复用一些已有的类,但是这些类的接口和我们当前需要的接口不匹配的情况。而适配器模式就可以让这些不兼容的类之间可以协作,方便地进行复用。

适配器模式有哪些角色?

1. 目标接口(Target):期望得到的接口,客户端调用的接口。
2. 原始类(Adaptee):现有的需要进行适配的接口。
3. 适配器(Adapter):将原始类的接口转换成了目标接口的类。

适配器模式的基本流程是什么?

1. 客户端通过调用 Target 接口中的方法,请求完成某个功能。
2. 适配器内部包装了一个 Adaptee 实例,并实现了 Target 接口。
3. 客户端调用适配器的方法,适配器实际上会调用 Adaptee 实例的方法。
4. 适配器将结果转换为目标接口对应的格式,返回给客户端。

适配器模式的优点是什么?

1. 提高代码的复用性,将原有的类适配到新的接口上之后可以在新的系统中重复使用。
2. 降低了类之间的耦合度,使用适配器模式可以让原有的类和新的系统之间解耦。
3. 提高了系统的灵活性和可扩展性,将来如果需要增加其他的接口类型,只需要增加相应的适配器即可。

适配器模式的缺点是什么?

1. 适配器模式增加了系统的复杂性,需要增加额外的适配器类来完成接口转换工作。
2. 适配器模式可能会造成一定的性能损失,因为需要增加额外的适配器层来完成数据转换。

适配器模式有哪些应用场景?

1. 系统需要使用现有的类,而这些类的接口不符合系统的需要。
2. 统一输入/输出接口,如日志记录、数据统计等。
3. 兼容性问题,如不同操作系统、不同数据库之间的数据交换。

总结一下适配器模式五个W和一个H:

- What:适配器模式,一种结构型设计模式,将不兼容的接口转换为符合客户端期望的接口。
- Why:用于复用现有的类,并让不兼容的接口之间可以进行协作。
- Who:目标接口、原始类、适配器。
- When:需要将一些不兼容的类适配到新的接口上,从而让它们可以在新系统中被重复使用。
- Where:适配器模式常用于统一输入/输出接口、解决兼容性问题等场景。
- How:客户端通过调用适配器的方法,适配器实际上会调用原始类的方法,并将结果转换为目标接口对应的格式后返回给客户端。

目标角色

    public interface IHelper
{
void Add<T>();
void Delete<T>();
void Update<T>();
void Query<T>();
}

被适配器角色

sqlserver、mysql、redis

适配器角色

SqlServerHelper
    public class SqlServerHelper : IHelper
{
public void Add<T>()
{
Console.WriteLine("This is {0} Add", this.GetType().Name);
}
public void Delete<T>()
{
Console.WriteLine("This is {0} Delete", this.GetType().Name);
}
public void Update<T>()
{
Console.WriteLine("This is {0} Update", this.GetType().Name);
}
public void Query<T>()
{
Console.WriteLine("This is {0} Query", this.GetType().Name);
}
}
MysqlHelper
    public class MysqlHelper : IHelper
{
public void Add<T>()
{
Console.WriteLine("This is {0} Add", this.GetType().Name);
}
public void Delete<T>()
{
Console.WriteLine("This is {0} Delete", this.GetType().Name);
}
public void Update<T>()
{
Console.WriteLine("This is {0} Update", this.GetType().Name);
}
public void Query<T>()
{
Console.WriteLine("This is {0} Query", this.GetType().Name);
}
}

对于一些第三方的组件方法,它里面已有类似的方法,这个时候我们可以采取 继承或 组合的方式,来做适配

    /// <summary>
/// 第三方提供的 openstack servicestack
/// 不能修改
/// </summary>
public class RedisHelper
{
public RedisHelper()
{
Console.WriteLine($"构造RedisHelper");
}
public void AddRedis<T>()
{
Console.WriteLine("This is {0} Add", this.GetType().Name);
}
public void DeleteRedis<T>()
{
Console.WriteLine("This is {0} Delete", this.GetType().Name);
}
public void UpdateRedis<T>()
{
Console.WriteLine("This is {0} Update", this.GetType().Name);
}
public void QueryRedis<T>()
{
Console.WriteLine("This is {0} Query", this.GetType().Name);
}
}

类适配器,通过继承的方式,在它上面实现目标IHelper

    /// <summary>
/// 类适配器
/// </summary>
public class RedisHelperInherit : RedisHelper, IHelper
{
public RedisHelperInherit()
{
Console.WriteLine($"构造{this.GetType().Name}");
} public void Add<T>()
{
base.AddRedis<T>();
} public void Delete<T>()
{
base.DeleteRedis<T>();
} public void Query<T>()
{
base.QueryRedis<T>();
} public void Update<T>()
{
base.UpdateRedis<T>();
}
}

对象适配器,通过组合的方式,在它上面实现目标IHelper

    public class RedisHelperObject : IHelper
{
public RedisHelperObject()
{
Console.WriteLine($"构造{this.GetType().Name}");
}
//属性注入 声明写死
private RedisHelper _RedisHelper = new RedisHelper(); ////构造函数 可以替换(需要抽象)
public RedisHelperObject(RedisHelper redisHelper)
{
this._RedisHelper = redisHelper;
} ////方法注入 可以替换(需要抽象)
public void SetObject(RedisHelper redisHelper)
{
this._RedisHelper = redisHelper;
} public void Add<T>()
{
this._RedisHelper.AddRedis<T>();
} public void Delete<T>()
{
this._RedisHelper.DeleteRedis<T>();
} public void Query<T>()
{
this._RedisHelper.QueryRedis<T>();
} public void Update<T>()
{
this._RedisHelper.UpdateRedis<T>();
}
}

运行测试

            {
//继承 既满足现有的规范调用,又没有修改RedisHelper
//类适配器模式
IHelper helper = new RedisHelperInherit();
helper.Add<Program>();
helper.Delete<Program>();
helper.Update<Program>();
helper.Query<Program>();
}
{
//组合 既满足现有的规范调用,又没有修改RedisHelper
//对象适配器
IHelper helper = new RedisHelperObject();
helper.Add<Program>();
helper.Delete<Program>();
helper.Update<Program>();
helper.Query<Program>();
}

源码下载:https://gitee.com/weilong2020/csharp_23_-design-patterns.git

C#设计模式06——适配器的写法的更多相关文章

  1. 设计模式C++描述----06.适配器(Adapter)模式

    一. 定义 适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. Adapter 模式的两种类别:类模式和对象模式. 二. 举例说明 实际中 ...

  2. Java设计模式06:常用设计模式之适配器模式(结构型模式)

    1. Java之适配器模式(Adapter Pattern) (1)概述:    将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类,可以在一起 ...

  3. 设计模式模式适配器(Adapter)摘录

    23种子GOF设计模式一般分为三类:创建模式.结构模型.行为模式. 创建模式抽象的实例,他们帮助建立一个系统,是独立于如何.这是一个这些对象和陈述的组合.创建使用继承一个类架构更改实例,一个对象类型模 ...

  4. Android 设计模式模式适配器

    自定义适配器模式:一类的接口,转换成客户的期望,也是一个接口.适配器使原本接口不是与类兼容可以无缝.下面两个图看起来更加清晰 watermark/2/text/aHR0cDovL2Jsb2cuY3Nk ...

  5. 架构设计之设计模式 (一) 适配器(Adapter)---提高复用性

    简介 简介是为了描述一下该模式是干嘛用的,为了让不了解该模式的人看了之后也有一些新的认识. 本文章分为两部分,第一部分主要介绍适配器模式:第二部分介绍该模式与相近模式的异同. 下午一直在讨论设计模式, ...

  6. Java设计模式之适配器设计模式(项目升级案例)

    今天是我学习到Java设计模式中的第三个设计模式了,但是天气又开始变得狂热起来,对于我这个凉爽惯了的青藏人来说,又是非常闹心的一件事儿,好了不管怎么样,目标还是目标(争取把23种Java设计模式接触一 ...

  7. PHP设计模式系列 - 适配器

    什么是适配器: 适配器设计模式只是将某个对象的接口适配为另一个对象所期望的接口. 设计情景: 假如我们原始的有一个UserInfo的类,提供用户信息的类,早起设计该类的时候,只实现了一个getUser ...

  8. 设计模式06: Adapter 适配器模式(结构型模式)

    Adapter 适配器模式(结构型模式) 适配(转换)的概念无处不在:电源转接头.电源适配器.水管转接头... 动机(Motivation)在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象 ...

  9. Java设计模式之适配器设计模式

    1.适配器模式( Adapter)定义将一个类的接口转换成客户希望的另外一个接口.Adapter 模式使得原来由于接口不兼容而不能一起工作的 那些类可以一起工作. 现实案例如下:  墙上电源类(22 ...

  10. 设计模式------Adapter(适配器)

    地址:http://blog.csdn.net/wuzhekai1985/article/details/6665542,仅供学习用. 适配器:STL实现了一种数据结构,称为双端队列(deque),支 ...

随机推荐

  1. CodeForces - 415B Mashmokh and Tokens

    Bimokh is Mashmokh's boss. For the following n days he decided to pay to his workers in a new way. A ...

  2. 华企盾DSC启动服务器提示“发生系统错误5”

    解决方法:没有管理员权限 导致,需要以管理员权限运行服务器安装包,覆盖安装一下

  3. IPv6实现内网穿透,极低成本保姆级教程

    摘要 一直想实现内网穿透从而达到随时随地可以连接到自己电脑的目的.尝试过使用一些付费的现成方案,但是价格偏高,而流量少得可怜,只能开放几个固定端口. 实现内网穿透的最大难点就在于拥有一个公网IP,但是 ...

  4. CSS之动画

    一.动画 动画类型 CSS3 可以创建动画,它可以取代许多网页动画图像.Flash 动画和 JavaScript 实现的效果. transform属性可以定义一些主要的动画属性, translate: ...

  5. LeetCode LRU缓存机制

    146. LRU缓存机制 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - ...

  6. 为什么MySQL单表不能超过2000万行?

    摘要:MySQL一张表最多能存多少数据? 本文分享自华为云社区<为什么MySQL单表不能超过2000万行?>,作者: GaussDB 数据库 . 最近看到一篇<我说MySQL每张表最 ...

  7. 亿级日活业务稳如磐石,华为云CodeArts PerfTest发布

    摘要:近日,华为云性能测试服务CodeArts PerfTest全新上线,提供低门槛.低成本的一站式云化性能测试解决方案. 本文分享自华为云社区<亿级日活业务稳如磐石,华为云CodeArts P ...

  8. 过亿云资源运维管控难?华为云CloudMap带你喝着咖啡做运维

    摘要:华为云站点数字化平台CloudMap携手华为云图引擎GES打造云服务全栈拓扑,网络流量路径和云服务动态依赖等空间关系数据,支撑现网运行态风险识别和分钟级定位定界,构建业界领先的数字化能力. 本文 ...

  9. 详解KubeEdge边缘网络项目EdgeMesh

    摘要:本文带大家进一步了解 EdgeMesh 的进展以及未来的规划. 本文分享自华为云社区<走向成熟的KubeEdge边缘网络项目EdgeMesh详解>,作者:华为云云原生团队 王杰章 . ...

  10. 使用Plist编辑器——简单入门指南

      本指南将介绍如何使用Plist编辑器.您将学习如何打开.编辑和保存plist文件,并了解plist文件的基本结构和用途.跟随这个简单的入门指南,您将掌握如何使用Plist编辑器轻松管理您的plis ...