.NET 设计模式—适配器模式(Adapter Pattern)

简介

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

在计算机编程中,适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。

适配器有类适配器和对象适配器两种类型,二者的意图相同,只是实现的方法和适用的情况不同。类适配器采用继承来实现,对象适配器则采用组合的方法来实现。

角色

  • 目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
  • 需要适配的类(Adaptee):需要适配的类或适配者类。
  • 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。  

优点

  • 通过适配器,客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单、更直接、更紧凑。
  • 复用了现存的类,解决了现存类和复用环境要求不一致的问题。
  • 将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码。
  • 一个对象适配器可以把多个不同的适配者类适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。

缺点

  • 对于对象适配器来说,更换适配器的实现过程比较复杂。(可以用工厂模式解决)

应用场景

  • 系统需要使用现有的类,而此类的接口不符合系统的需要。
  • 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。这些源类不一定有很复杂的接口。
  • 仅对对象适配器而言,在设计里,需要改变多个已有子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器,而这不太实际。

案例

我们开发了一个项目,项目中采用了一个第三方的日志组件来记录日志,但是现在第三方日志组件实现的,现在我们自己开发了一个日志组件,我们想把项目中的日志组件替换为我们自己开发的,但是我们自己的开发的日志组件并没有实现第三方组件的接口,这个时候要怎么处理?

对象适配器实现(推荐)

  • 目标接口
/// <summary>
/// 目标接口
/// </summary>
public interface ILog
{/// <summary>/// 写日志的方法/// </summary>public void Write(string logCommand);
}
  • 需要适配的类
/// <summary>
/// 新开发的的日志接口类
/// </summary>
public abstract class ILogAbapter
{/// <summary>/// 新的写日志的方法/// </summary>/// <param name="logCommand"></param>public abstract void NewWrite(string logCommand);
}/// <summary>
/// 需要适配的数据库日志类
/// </summary>
public class DbLog : ILogAbapter
{public override void NewWrite(string logCommand){Console.WriteLine($"记录到数据库中:{logCommand}");}
}/// <summary>
/// 需要适配的文件日志类
/// </summary>
public class FileLog : ILogAbapter
{public override void NewWrite(string logCommand){Console.WriteLine($"记录到日志文件中:{logCommand}");}
}
  • 适配器
/// <summary>
/// 对象适配器
/// </summary>
public class LogAdapter : ILog
{private readonly ILogAbapter _logAdapter = null;public LogAdapter(ILogAbapter logAdapter){_logAdapter = logAdapter;}public void Write(string logCommand){_logAdapter.NewWrite(logCommand);}
}
  • 上层应用调用
{#region 对象适配器LogAdapter fileLog = new LogAdapter(new FileLogAdapter());fileLog.Write("hello word");LogAdapter dbLog = new LogAdapter(new DbLogAdapter());dbLog.Write("hello word");#endregion
}

类适配器实现

  • 目标接口
/// <summary>
/// 目标接口
/// </summary>
public interface ILog
{/// <summary>/// 写日志的方法/// </summary>public void Write(string logCommand);
}
  • 需要适配的类
/// <summary>
/// 新开发的的日志接口类
/// </summary>
public abstract class ILogAbapter
{/// <summary>/// 新的写日志的方法/// </summary>/// <param name="logCommand"></param>public abstract void NewWrite(string logCommand);
}/// <summary>
/// 需要适配的数据库日志类
/// </summary>
public class DbLog : ILogAbapter
{public override void NewWrite(string logCommand){Console.WriteLine($"记录到数据库中:{logCommand}");}
}/// <summary>
/// 需要适配的文件日志类
/// </summary>
public class FileLog : ILogAbapter
{public override void NewWrite(string logCommand){Console.WriteLine($"记录到日志文件中:{logCommand}");}
}
  • 适配器
/// <summary>
/// 数据库日志适配器
/// </summary>
public class DbLogAdapter : DbLog, ILog
{public void Write(string logCommand){NewWrite(logCommand);}
}/// <summary>/// 文件日志适配器/// </summary>public class FileLogAdapter : FileLog, ILog{public void Write(string logCommand){NewWrite(logCommand);}}
  • 上层应用调用
{#region 类适配器ILog fileLog = new FileLogAdapter();fileLog.Write("hello word");ILog dbLog = new DbLogAdapter();dbLog.Write("hello word");#endregion
}

总结

  • 对象适配用处是,可以使Adaptee不必实现不需要的方法,具体就是其表现形式就是父类实现缺省方法,而子类只需实现自己独特的方法。
  • 适配器类可以是抽象类。
  • 带参数的适配器模式。使用这种办法,适配器类可以根据参数返还一个合适的实例给客户端。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/299173.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C刊级 | Matlab实现GWO-BiTCN-BiGRU-Attention灰狼算法优化双向时间卷积双向门控循环单元融合注意力机制多变量回归预测

C刊级 | Matlab实现GWO-BiTCN-BiGRU-Attention灰狼算法优化双向时间卷积双向门控循环单元融合注意力机制多变量回归预测 目录 C刊级 | Matlab实现GWO-BiTCN-BiGRU-Attention灰狼算法优化双向时间卷积双向门控循环单元融合注意力机制多变量回归预测效果一览基本介绍程序设计参考…

【IEEE STD 1801】——Introduction

Introduction 本标准的目的是提供便携、低功耗的设计规范&#xff0c;这些规范可以在整个电子系统设计、分析、验证和实现流程中与各种商业产品一起使用。 当电子设计自动化(EDA)行业在20世纪80年代开始创建用于指定、仿真和实现数字电子电路的功能规范的标准时&#xff0c;主…

Midjourney艺术家分享|By Moebius

Moebius&#xff0c;本名让吉拉德&#xff08;Jean Giraud&#xff09;&#xff0c;是一位极具影响力的法国漫画家和插画师&#xff0c;以其独特的科幻和幻想风格而闻名于世。他的艺术作品不仅在漫画领域内受到高度评价&#xff0c;也为电影、时尚和广告等多个领域提供了灵感。…

练习 16 Web [极客大挑战 2019]LoveSQL

extractvalue(1,concat(‘~’, (‘your sql’) ) )报错注入&#xff0c;注意爆破字段的时候表名有可能是table_name不是table_schema 有登录输入框 常规尝试一下 常规的万能密码&#xff0c;返回了一个“admin的密码”&#xff1a; Hello admin&#xff01; Your password is…

2023年港澳台联考中的招生大户武汉大学

导读 随着小米集团雷军近期的热度不断上升&#xff0c;很多家长开始关注到武汉大学这样一所历史悠久的亚洲知名大学。小米集团的董事长雷军就是毕业于武汉大学的校友。今天我们一起来看一下&#xff0c;2023年港澳台联招中的武汉大学&#xff01; 学校简介 武汉大学是一所位于湖…

Redis(性能管理、主从复制、哨兵模式)概述及部署

目录 一、性能管理 1、查看Redis内存使用 2、内存碎片率 3、跟踪内存碎片率 4、内存使用率 5、内回收key 二、Redis集群有三种模式 三、Redis主从复制 1、主从复制的概念 2、主从复制的作用 3、主从复制的流程 4、搭建Redis主从复制 1.环境准备 2.安装Redis&#…

SV学习笔记(六)

文章目录 覆盖率类型写在前面代码覆盖率断言覆盖率功能覆盖率漏洞率曲线 功能覆盖策略收集信息而非数据只测量需要的内容验证的完备性 覆盖组写在前面在类里定义covergroup 数据采样写在前面coverpoint和binbin的创建和应用命名coverpoint和bin条件覆盖率翻转覆盖率wildcard覆盖…

Linux——线程控制

目录 前言 一、线程创建 1.创建线程 2.线程传递结构体 3.创建多线程 4.收到信号的线程 二、线程终止 三、线程等待 四、线程分离 五、取消线程 六、线程库管理的原理 七、站在语言角度理解pthread库 八、线程的局部存储 前言 前面我们学习了线程概念和线程创建&…

C语言实现快速排序算法

1. 什么是快速排序算法 快速排序的核心思想是通过分治法&#xff08;Divide and Conquer&#xff09;来实现排序。 算法的基本步骤是: 1. 选择一个基准值&#xff08;通常是数组中的某个元素&#xff09;&#xff0c;将数组分成两部分&#xff0c;使得左边的部分所有元素都小于…

C和C++内存管理

目录&#xff1a; 一&#xff1a;C和C内存分布 二&#xff1a;C动态内存管理方式 三&#xff1a;C动态内存管理方式 四&#xff1a;operator new与operator delete函数 五&#xff1a;new和delete的实现原理 六&#xff1a;定位new表达式(placement-new) 七&#xff1…

ubuntu-server部署hive-part2-安装hadoop

参照 https://blog.csdn.net/qq_41946216/article/details/134345137 操作系统版本&#xff1a;ubuntu-server-22.04.3 虚拟机&#xff1a;virtualbox7.0 安装hadoop ​​​​​​下载上传 下载地址 https://archive.apache.org/dist/hadoop/common/hadoop-3.3.4/ 以root用…

用C/C++加Easyx实现俄罗斯方块游戏(爆肝4万字,完全免费)

前言 相信大家一定玩过俄罗斯方块这款小游戏&#xff0c;简单容易上手是老少皆宜的小游戏&#xff0c;今天大家就跟着我来实现这个小游戏吧&#xff01;让自己学的C语言有用武之地。 为了让俄罗斯方块的开发更为简单些&#xff0c;图像更为丰富&#xff0c;在这里就利用了Easyx…

设计模式总结-原型设计模式

原型设计模式 模式动机模式定义模式结构模式分析深拷贝和浅拷贝原型模式实例与解析实例一&#xff1a;邮件复制&#xff08;浅克隆&#xff09;实例二&#xff1a;邮件复制&#xff08;深克隆&#xff09; 模式动机 在面向对象系统中&#xff0c;使用原型模式来复制一个对象自…

vue使用iview导航栏Menu activeName不生效

activeName不生效 一、问题一、解决方案&#xff0c; 一、问题 根据ivew官网的提示&#xff0c;设置了active-name和open-names以后&#xff0c;发现不管是设置静态是数据还是设置动态的数据&#xff0c;都不生效 一、解决方案&#xff0c; 在设置动态名称的时候&#xff0c…

Centos7环境下安装MySQL8详细教程

1、下载mysql安装包 下载哪个版本&#xff0c;首先需要确定一下系统的glibc版本&#xff0c;使用如下命令&#xff1a; rpm -qa | grep glibc ​​​​​​​ 2、检查是否安装过mysql ps:因为以前用yum安装过&#xff0c;所以先用yum卸载。如果不是此方式或者没安装过则跳过…

基于SpringBoot Vue求职招聘系统

一、&#x1f4dd;功能介绍 基于SpringBoot Vue招聘系统的设计与实现 角色&#xff1a;管理员、企业、用户 管理员&#xff1a;管理员进入主页面&#xff0c;主要功能包括对个人中心、企业管理、用户管理、岗位类型管理、招聘信息管理、应聘记录管理、留言反馈、系统管理等进…

笛子基础入门

文章目录 1.符号2. 笛子指法说明3. 曲谱3.1 年轮3.2 生生世世爱 1.符号 笛子简谱&#xff1a;由七个基本数字组成&#xff08;1234567&#xff09;&#xff1b;高音在数字上面加一“.”&#xff0c;低音则在下面加一“.”&#xff0c;不加点则是中音&#xff1b;数字后面加横线…

Linux从入门到精通 --- 2.基本命令入门

文章目录 第二章&#xff1a;2.1 Linux的目录结构2.1.1 路径描述方式 2.2 Linux命令入门2.2.1 Linux命令基础格式2.2.2 ls命令2.2.3 ls命令的参数和选项2.2.4 ls命令选项的组合使用 2.3 目录切换相关命令2.3.1 cd切换工作目录2.3.2 pwd查看当前工作目录2.4 相对路径、绝对路径和…

基于MPPT的风力机发电系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1风能与风力发电机模型 4.2风力机功率特性与最大功率点 4.3 MPPT 5.完整工程文件 1.课题概述 基于MPPT的风力机发电系统simulink建模与仿真。MPPT使用S函数编写实现。基于最大功率点跟踪&#xff08…

日志服务 HarmonyOS NEXT 日志采集最佳实践

作者&#xff1a;高玉龙&#xff08;元泊&#xff09; 背景信息 随着数字化新时代的全面展开以及 5G 与物联网&#xff08;IoT&#xff09;技术的迅速普及&#xff0c;操作系统正面临前所未有的变革需求。在这个背景下&#xff0c;华为公司自主研发的鸿蒙操作系统&#xff08…