当前位置:首页 > 日记 > 正文

.NET适配器模式讲解

.NET适配器模式讲解

适配器模式简介:

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

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

适配器模式结构图:

引入实例进行说明:

以日志记录程序为Demo说明,在任何一套软件中都会有对应的日志管理模块,假如如果我们在开发软件中的日记记录采用第三方的日志组件进行日志记录,它采用的是Log.Write("写日志");的方式我们的程序在开发中,大量实例化日记记录对象,采用的Log.Write()方式进行日志记录,但是现在第三方的日志组件现在不免费了,需要收费了,于是我们打算使用一种新的日志管理模块,只不过它提供给我们的API接口是采用Log.WriteLog("新的写日志的方式");进行日志记录。这个时候问题就出现了,如何应对这种迁移的变化

类适配器模式

1.原来日志的接口,采用的是Write(“写日志”);方法

  /// <summary>  /// 原来的日志记录接口  /// </summary>  public interface ILogTarget  {    /// <summary>    /// 原来的写日志方法    /// </summary>    void Write(string info);  }

2.然而现在的写日志的接口,采用的是WriteLog("写日志");里面实现了写日志的新的方式:将日志写到文件中,数据库中

  /// <summary>  /// 抽象写日志类  /// </summary>  public abstract class LogAdaptee  {    /// <summary>    /// 写日志    /// </summary>    public abstract void WriteLog(string info);  }
  /// <summary>  /// 写文件日志记录  /// </summary>  public class FileLog:LogAdaptee  {    /// <summary>    /// 写日志到文件中    /// </summary>    public override void WriteLog(string info)    {      Console.WriteLine("记录到文本文件:"+info);    }  }
  /// <summary>  /// 往数据库中写日志  /// </summary>  public class DatabaseLog:LogAdaptee  {    /// <summary>    /// 重写写日志方法    /// </summary>    public override void WriteLog(string info)    {      Console.WriteLine("记录到数据库:"+info);    }  }

3.如何使用者两个新对象中的方式,替换原来的写日志的方式?

  /// <summary>  /// 采用新的写日志的方式,写入到数据库中  /// </summary>  public class DatabaseLogAdapter:DatabaseLog,ILogTarget  {    /// <summary>    /// 在重写ILogTarget接口中的的Write方法里面调用新的写日志的方式WriteLog    /// </summary>    public void Write(string info)    {      WriteLog(info);    }  }  /// <summary>  /// 采用新的写日志的方式,写入到文本文件  /// </summary>  public class FileLogAdapter : FileLog, ILogTarget  {    /// <summary>    /// 在重写ILogTarget接口中的的Write方法里面调用新的写日志的方式WriteLog    /// </summary>    public void Write(string info)    {      this.WriteLog(info);    }  }

4.调用依据使用的原来写日志的方法,但是确实使用的新的写日志的方式:

  /// <summary>  /// 类 适配器模式(Adapter Pattern)  /// </summary>  class Program  {    static void Main(string[] args)    {      ILogTarget dbLog = new DatabaseLogAdapter();      dbLog.Write("程序启动成功");      dbLog = new FileLogAdapter();      dbLog.Write("程序启动成功");    }  }

对象适配器模式

1.方式采用的是类适配器的方式实现了新的日志功能的迁移变化,下面我们使用对象适配器,可以区别发现两种方式的特别之处。原来写日志的方法依旧不变:Write("写日志");

  /// <summary>  /// 原来的日志记录接口  /// </summary>  public interface ILogTarget  {    /// <summary>    /// 原来的写日志方法    /// </summary>    void Write(string info);  }

2.现在的写日志的接口,采用的是WriteLog("写日志");里面实现了写日志的新的方式:将日志写到文件中,数据库中:

  /// <summary>  /// 抽象写日志类  /// </summary>  public abstract class LogAdaptee  {    /// <summary>    /// 写日志    /// </summary>    public abstract void WriteLog(string info);  }
  /// <summary>  /// 写文件日志记录  /// </summary>  public class FileLog:LogAdaptee  {    /// <summary>    /// 写日志到文件中    /// </summary>    public override void WriteLog(string info)    {      Console.WriteLine("记录到文本文件:"+info);    }  }
  /// <summary>  /// 往数据库中写日志  /// </summary>  public class DatabaseLog:LogAdaptee  {    /// <summary>    /// 重写写日志方法    /// </summary>    public override void WriteLog(string info)    {      Console.WriteLine("记录到数据库:"+info);    }  }

3.上面我们添加了FileLogAdapter 类,DatabaseLogAdapter类,继承了FileLog,DatabaseLog, ILogTarget接口,重写Write方法里面调用新的写日志的方式WriteLog,使用这样的方式进行了迁移变化。下面使用对象适配:

  /// <summary>  /// 对象适配,继承ILogTarget,里面有LogAdaptee抽象日志类对象。  /// </summary>  public class LogAdapter:ILogTarget  {    /// <summary>    /// 抽象写日志类    /// </summary>    private LogAdaptee _adaptee;    public LogAdapter(LogAdaptee adaptee)    {      this._adaptee = adaptee;    }    public void Write(string info)    {      _adaptee.WriteLog(info);    }  }

4.在程序中的调用:

  /// <summary>  /// 对象适配器模式(Adapter Pattern)  /// </summary>  class Program  {    static void Main(string[] args)    {      ILogTarget dbLog = new LogAdapter(new DatabaseLog());      dbLog.Write("程序启动成功");      ILogTarget fileLog = new LogAdapter(new FileLog());      fileLog.Write("程序启动成功");    }  }

比较两者的迁移变化,在类适配方式中,我们得到的适配器类DatabaseLogAdapter和FileLogAdapter具有它所继承的父类的所有的行为,同时也具有接口ILogTarget的所有行为,这样其实是违背了面向对象设计原则中的类的单一职责原则,而对象适配器则更符合面向对象的精神,所以在实际应用中不太推荐类适配这种方式。假设我们要适配出来的类在记录日志时同时写入文件和数据库,那么用对象适配器我们会这样去写:

  /// <summary>  /// 对象适配,继承ILogTarget,里面有LogAdaptee抽象日志类对象。  /// </summary>  public class LogAdapter:ILogTarget  {    /// <summary>    /// 抽象写日志类    /// </summary>    private LogAdaptee _adapteed;    /// <summary>    /// 抽象写日志类    /// </summary>    private LogAdaptee _adapteef;    public LogAdapter(LogAdaptee adapteed, LogAdaptee adapteef)    {      this._adapteed = adapteed;      this._adapteef = adapteef;    }    public void Write(string info)    {      _adapteed.WriteLog(info);      _adapteef.WriteLog(info);    }  }

调用:

  /// <summary>  /// 对象适配器模式(Adapter Pattern)  /// </summary>  class Program  {    static void Main(string[] args)    {      //同时写日志到文件和数据库      ILogTarget dbLog = new LogAdapter(new FileLog(), new DatabaseLog());      dbLog.Write("程序启动成功");    }  }

如果改用类适配器:我们难道使用这样的写法达到目的?

  public class DatabaseLogAdapter : DatabaseLog, FileLog, ILogTarget  {    public void Write(string info)    {      this.WriteLog(info);    }  }

结果肯定是不能的,一个类不能具有多个基类,这样写明细有错误。所有针对不同的情况,我们应该采用合适的方式去进行适配调度。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

相关文章

如何在一个Word文档文件设置一个立

如何在一个Word文档文件设置一个立

文件,设置,文档,如何在,电脑软件,无需边印,它是打印机本身的功能,称为全振幅印刷。但并非所有的印刷机都有此功能。以下是你的小文件,关于word文件的设置没有边框打印,希望对你有所帮助。 没有边框打印的Word文件设置 1。如果打印机没有这个…

如何使用ps动作的录制和编辑

如何使用ps动作的录制和编辑

如何使用,编辑,动作,电脑软件,ps,在我们介绍使用PS构建动作处理图片的几个例子之前,本章我们将学习我们自己的记录操作,这将是ps动作应用程序中最吸引人的部分之一。结合批量命令,您可以根据您的想法快速编辑数千张图片。 ps动作的录制和编辑…

MySQL启动1067错误并纠正在字符集

MySQL启动1067错误并纠正在字符集

字符集,启动,重新启动,错误,恢复,下载解压的官方网站mysql-5.6.37-winx64.zip版本,修改配置文件,安装服务,直接使用; 中国有一种混乱,解决方法: 在mysql-5.6.37-winx64目录,一个新的my.ini文件创建和配置(内容可以在互联网上找到或手动配置我的默…

PHP5.6新增加的可变函数参数用法分

PHP5.6新增加的可变函数参数用法分

函数参数,电脑软件,本文实例讲述了PHP5.6新增加的可变函数参数用法。分享给大家供大家参考,具体如下:今天无事,看了下PHP手册。发现PHP版本更新增加不少东西。下面就说说其中的PHP5.6更新中新增加的可变函数参数。代码1:function sum(...$numbe…

photoshop动作怎么安装

photoshop动作怎么安装

安装,动作,电脑软件,photoshop,   ps在绘图领域是当之无愧的霸主,它的各种功能简单方便,而photoshop中动作的应用更是给设计带来了方便,网络上提供了各式各样的现成录制的动作,所以学会安装动作是最基本的要领。本文为大家介绍怎么…

电脑版王者荣耀怎么玩?

电脑版王者荣耀怎么玩?

荣耀,王者,电脑软件,TGP是由腾讯推出的一款游戏助手平台,大部分玩家都会使用TGP启动游戏,其实TGP不仅可以玩网络游戏,手游也可以在TGP上玩耍,好多小伙伴都不知道吧,下面小编就给大家详细讲解一下具体的方法,快来看看吧!方法/步骤:1、下载腾讯的游…

LNMPA遇到504 Gateway time-out错

LNMPA遇到504 Gateway time-out错

解决方法,错误,电脑软件,LNMPA,time,Nginx的特点是处理静态很给力,Apache的特点是处理动态很稳定,两者结合起来便是LNMPA,nginx处理前端,apache处理后端,这样处理静态会很快,处理动态会很稳定。当我以为安装完成以后便万事大吉,不料更新网站的时候…

PHP手机号中间四位用星号*代替显示

PHP手机号中间四位用星号*代替显示

显示,星号,四位,手机号,实例,在显示用户列表的场景中,一般用到手机号的显示时都需要对手机号进行处理,一般是把中间的四位换成星号****,我本人用php处理的思路是进行替换,用****替换手机号的中间四位代码如下:$all_lottery_logs = ********; …

excel表格设置渐变色背景的方法exc

excel表格设置渐变色背景的方法exc

设置,渐变色,方法,表格,背景,  Excel中经常需要使用到设置渐变色为背景的技巧,渐变色背景具体该如何进行设置呢?下面是由小编分享的excel表格设置渐变色背景的方法,以供大家阅读和学习。excel表格设置渐变色背景的方法1步骤1:同样全选表格,右…

微信小程序选择和放大预览功能

微信小程序选择和放大预览功能

选择,功能,程序,电脑软件,微信小,视频中,老师也是看着官方文档,为学生们讲解,微信提供了系统的方法来选择图片.wx.chooseImage({})此方法是用来选择图片的方法,具体使用如下:data: { avatarUrl:null },首先在数据中定义接收数据的变量,然后…

MySQL优化之使用连接 | join代替子

MySQL优化之使用连接 | join代替子

优化,子查询,连接,电脑软件,MySQL,使用连接(JOIN)来代替子查询(Sub-Queries)MySQL从4.1开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。例如,我们要将客户基本信息表…

oracle逻辑运算符及其优先级简介

oracle逻辑运算符及其优先级简介

逻辑运算符,优先级,简介,电脑软件,oracle,Oracle的逻辑运算符也是SQL语句中的一个重要因素,总共有三个。 逻辑运算符 意义 和 如果这两个条件都是真的,则双值运算符的值为true。 或 如果两个条件之一是真的,则双值运算符的值是真的。 不 如果…