C#设计模式06——适配器的写法
什么是适配器模式?
适配器模式是一种结构型设计模式,用于将现有接口转换为符合客户端期望的接口。适配器模式允许不兼容的类可以相互协作。
为什么需要适配器模式?
在实际开发中,经常会遇到需要复用一些已有的类,但是这些类的接口和我们当前需要的接口不匹配的情况。而适配器模式就可以让这些不兼容的类之间可以协作,方便地进行复用。
适配器模式有哪些角色?
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——适配器的写法的更多相关文章
- 设计模式C++描述----06.适配器(Adapter)模式
一. 定义 适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. Adapter 模式的两种类别:类模式和对象模式. 二. 举例说明 实际中 ...
- Java设计模式06:常用设计模式之适配器模式(结构型模式)
1. Java之适配器模式(Adapter Pattern) (1)概述: 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类,可以在一起 ...
- 设计模式模式适配器(Adapter)摘录
23种子GOF设计模式一般分为三类:创建模式.结构模型.行为模式. 创建模式抽象的实例,他们帮助建立一个系统,是独立于如何.这是一个这些对象和陈述的组合.创建使用继承一个类架构更改实例,一个对象类型模 ...
- Android 设计模式模式适配器
自定义适配器模式:一类的接口,转换成客户的期望,也是一个接口.适配器使原本接口不是与类兼容可以无缝.下面两个图看起来更加清晰 watermark/2/text/aHR0cDovL2Jsb2cuY3Nk ...
- 架构设计之设计模式 (一) 适配器(Adapter)---提高复用性
简介 简介是为了描述一下该模式是干嘛用的,为了让不了解该模式的人看了之后也有一些新的认识. 本文章分为两部分,第一部分主要介绍适配器模式:第二部分介绍该模式与相近模式的异同. 下午一直在讨论设计模式, ...
- Java设计模式之适配器设计模式(项目升级案例)
今天是我学习到Java设计模式中的第三个设计模式了,但是天气又开始变得狂热起来,对于我这个凉爽惯了的青藏人来说,又是非常闹心的一件事儿,好了不管怎么样,目标还是目标(争取把23种Java设计模式接触一 ...
- PHP设计模式系列 - 适配器
什么是适配器: 适配器设计模式只是将某个对象的接口适配为另一个对象所期望的接口. 设计情景: 假如我们原始的有一个UserInfo的类,提供用户信息的类,早起设计该类的时候,只实现了一个getUser ...
- 设计模式06: Adapter 适配器模式(结构型模式)
Adapter 适配器模式(结构型模式) 适配(转换)的概念无处不在:电源转接头.电源适配器.水管转接头... 动机(Motivation)在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象 ...
- Java设计模式之适配器设计模式
1.适配器模式( Adapter)定义将一个类的接口转换成客户希望的另外一个接口.Adapter 模式使得原来由于接口不兼容而不能一起工作的 那些类可以一起工作. 现实案例如下: 墙上电源类(22 ...
- 设计模式------Adapter(适配器)
地址:http://blog.csdn.net/wuzhekai1985/article/details/6665542,仅供学习用. 适配器:STL实现了一种数据结构,称为双端队列(deque),支 ...
随机推荐
- [ABC299F] Square Subsequence
Problem Statement You are given a string $S$ consisting of lowercase English letters. Print the numb ...
- erp——绩效考核系统——软件需求规格说明书
绩效考核系统--软件需求规格说明书 引言 1.1编写目的:此文件需求说明书主要是为了开发人员能了解系统之间的关系,使用者能明白系统的使用方法,另外,可以供一些学习的小白进行参考,提供需要的人参考软件需 ...
- 4 HTTP的“四层”和“七层”
目录 1 四层:TCP/IP 网络分层模型 2 七层:OSI网络分层模型 3 TCP/IP 协议栈的工作方式 1 四层:TCP/IP 网络分层模型 四层是指TCP/IP 网络分层模型. 第一层:&qu ...
- 火眼金睛破局ES伪慢查询
一.问题现象 服务现象 服务接口的TP99性能降低 ES现象 YGC:耗时极其不正常, 峰值200+次,耗时7s+ FULL GC:不正常,次数为1但是频繁,STW 5s 慢查询:存在慢查询5+ 二 ...
- 87 GB 模型种子,GPT-4 缩小版,超越ChatGPT3.5,多平台在线体验
瞬间爆火的Mixtral 8x7B 大家好,我是老章 最近风头最盛的大模型当属Mistral AI 发布的Mixtral 8x7B了,火爆程度压过Google的Gemini. 缘起是MistralAI ...
- Python——第二章:文件操作
文件操作 1. 找到这个文件. 双击打开它 open(文件路径, mode="", encoding="") 文件路径: 1. 绝对路径 d:/test/xxx ...
- Ubuntu apt-get 的使用
在Ubuntu中,可以使用apt-get命令来管理软件包.下面是一些常见的apt-get命令及其用法: 安装软件包: sudo apt-get install <package> 其中,& ...
- C语言基础之四舍五入
要求:输入任意的2个小数:将这2个小数相加并显示结果:将结果按四舍五入方法转换成整数并显示. 0.0到0.4的数加上0.5不会进位,而0.5到0.9的数加上0.5会进位.所以可以依靠这个特点让计算后的 ...
- 【scikit-learn基础】--『监督学习』之 贝叶斯分类
贝叶斯分类是一种统计学分类方法,基于贝叶斯定理,对给定的数据集进行分类.它的历史可以追溯到18世纪,当时英国统计学家托马斯·贝叶斯发展了贝叶斯定理,这个定理为统计决策提供了理论基础. 不过,贝叶斯分类 ...
- MyBatis 的缓存处理
作为常见的 ORM 框架,在使用 MyBatis 的过程中可以针对相关的查询进行缓存处理以提高查询的性能.本文将简要介绍一下 MyBatis 中默认的一级缓存和二级缓存,以及自定义缓存的处理 MyBa ...