【设计模式】C#实现结构型模式之-适配器模式
本文最后更新于35 天前,其中的信息可能已经过时,如有错误请发送邮件到2289035571@QQ.COM

前言

在实际的开发过程中,由于应用环境的变化(例如使用语言的变化),我们需要的实现在新的环境中没有现存对象可以满足,但是其他环境却存在这样现存的对象。那么如果将“将现存的对象”在新的环境中进行调用呢?解决这个问题的办法就是我们本文要介绍的适配器模式——使得新环境中不需要去重复实现已经存在了的实现而很好地把现有对象(指原来环境中的现有对象)加入到新环境来使用。

分为类适配模式和对象适配模式

通俗解释

假设我现在有一个电风扇,插头是2孔的。但我买了一个插排全是3孔的。我现在需要把这个2孔插头插入3孔插排中。(像之前会考虑掰弯,这也算适配了,但现在无法掰弯的情况下)

我们需要做一个适配器,在2孔插头和3孔插排之间加一层。

这个适配器就是做到将2孔插头转换为3孔插头,这样子就可以满足要求。

类适配模式:

1、定义接口,IHelper。接口中有增删改查方法

2、现在有两个数据库 MysqlHelper类,SqlserverHelper类。实现IHelper接口的方法

3、新增了一个RedisHelper,此时无法使用IHelper(无法适配,方法不一致)

4、新增RedisClassHelper,继承IHelper和RedisHelper。实现父类方法 base.xx方法();

代码实现

  • IHelper接口
public interface IHelper
{
    //增删查改 CRUD
    void Add();
    void Delete();
    void Query();
    void Update();       
}
  • MysqlHelper类 继承IHelper接口
public class MysqlHelper : IHelper
{
    public void Add()
    {
        Console.WriteLine($"Add  {this.GetType().Name}");
    }

    public void Delete()
    {
        Console.WriteLine($"Delete {this.GetType().Name}");
    }

    public void Query()
    {
        Console.WriteLine($"Query {this.GetType().Name}");
    }

    public void Update()
    {
        Console.WriteLine($"Update {this.GetType().Name}");
    }
}
  • SqlServerHelper类继承IHelper接口
public class SqlServerHelper : IHelper
{
    public void Add()
    {
        Console.WriteLine($"Add {this.GetType().Name}");
    }

    public void Delete()
    {
        Console.WriteLine($"Delete {this.GetType().Name}");
    }

    public void Query()
    {
        Console.WriteLine($"Query {this.GetType().Name}");
    }

    public void Update()
    {
        Console.WriteLine($"Update {this.GetType().Name}");
    }
}
  • 新增的RedisHelper。无法继承IHelper。因为方法不一致,无法匹配。
/// <summary>
/// 新增的ReidsHelper 与其他数据库不一样。她或许是第三方提供的
/// 此时我们可以使用适配器模式,使用类适配器或者对象适配器
/// 推荐使用对象适配器,使用组合灵活性更强
/// </summary>
public class RedisHelper
{
    public void AddRedis()
    {
        Console.WriteLine($"AddRedis  {this.GetType().Name}");
    }

    public void DeleteRedis()
    {
        Console.WriteLine($"DeleteRedis {this.GetType().Name}");
    }

    public void QueryRedis()
    {
        Console.WriteLine($"QueryRedis {this.GetType().Name}");
    }

    public void UpdateRedis()
    {
        Console.WriteLine($"UpdateRedis {this.GetType().Name}");
    }
}
  • 创建RedisClassHelper类,RedisHelper和IHelper。ps:必须先继承父类,否则会报错
  • 使用类适配器 继承强耦合 使用base,调用RedisHelper的方法
/// <summary>
/// 类适配器  继承强耦合 使用base,调用RedisHelper的方法  
/// </summary>
public class RedisClassHelper : RedisHelper,IHelper 
{
    public void Add()
    {
        base.AddRedis();
    }

    public void Delete()
    {
        base.DeleteRedis();
    }

    public void Query()
    {
        base.QueryRedis();
    }

    public void Update()
    {
        base.UpdateRedis();
    }
}

对象适配模式:

组合,使用类来调用方法

继承是强耦合,子类会继承父类的所有方法(需要的,不需要的都会继承下来),不灵活

组合可以使用构造函数,让上端去传递。

一般来说是组合优于继承

组合:

在新类里创建现有类的对象。我们把这种方式称之为组合,因为新类是由现有的类组合而成

1、定义接口,IHelper。增删改查方法

2、现在有两个数据库 MysqlHelper类,SqlserverHelper类。实现IHelper接口的方法

3、新增了一个RedisHelper,但是无法使用IHelper

4、新增RedisObjectHelper,继承IHelper。可以使用构造方法,让上端传入RedisHelper对象。然后实现IHepler接口的方法。在方法中,调用RedisHelper对象的方法。

代码实现

上述三步都是一致的,这里就不赘述代码了。只贴出了不一样的代码

  • 创建RedisObjectHelper类,继承IHelper接口
public class RedisObjectHelper : IHelper
{
    private RedisHelper _redisHelper;
    public RedisObjectHelper(RedisHelper redisHelper)
    {
        this._redisHelper = redisHelper;
    }
    public void Add()
    {
        _redisHelper.AddRedis();
    }

    public void Delete()
    {
        _redisHelper.DeleteRedis();
    }

    public void Query()
    {
        _redisHelper.QueryRedis();
    }

    public void Update()
    {
        _redisHelper.UpdateRedis();
    }
}

适用场景

项目集成的时候使用,最好是在项目的后期用,接口固定的情况下,需要新增一个适配

比如DataAdapter。适配不同的数据源。

注:这个模式其实有点亡羊补牢的意思,不得已而为之。如果是自己的项目,应该在出现这种情况的时候,首先考虑能不能重构代码,优化接口,除非是双方都不太容易修改的情况下,才考虑使用该模式。如果需要使用第三方的开发组件,和我们自己系统的接口不同,而我们也完全没必要为了迎合它而改动自己的接口。此时可以考虑适配器模式来解决问题。

文章拓展资料

觉得有帮助可以投喂下博主哦~感谢!
作者:Lincol
本文链接:https://www.lincol29.cn/adapterpattern
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0协议转载请注明文章地址及作者哦~

评论

  1. Windows Edge
    1 月前
    2024-6-19 21:42:00

    有点像用一个方法包装了另一个方法来实现曲线改名?(大雾)

    • lincol29
      GoodBoyboy
      iPhone Chrome
      1 月前
      2024-6-20 7:48:21

      设计模式的出现就是解决一类问题的,在解决一类问题的时候又会出现新的问题。解决不了就向上包一层,在包一层的时候你可能感觉就是改名而已😂

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇