前言
在实际的开发过程中,由于应用环境的变化(例如使用语言的变化),我们需要的实现在新的环境中没有现存对象可以满足,但是其他环境却存在这样现存的对象。那么如果将"将现存的对象"在新的环境中进行调用呢?解决这个问题的办法就是我们本文要介绍的适配器模式------使得新环境中不需要去重复实现已经存在了的实现而很好地把现有对象(指原来环境中的现有对象)加入到新环境来使用。
分为类适配模式和对象适配模式
通俗解释
假设我现在有一个电风扇,插头是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。因为方法不一致,无法匹配。
///
/// 新增的ReidsHelper 与其他数据库不一样。她或许是第三方提供的 /// 此时我们可以使用适配器模式,使用类适配器或者对象适配器 /// 推荐使用对象适配器,使用组合灵活性更强 /// 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的方法
///
/// 类适配器 继承强耦合 使用base,调用RedisHelper的方法 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。适配不同的数据源。
注:这个模式其实有点亡羊补牢的意思,不得已而为之。如果是自己的项目,应该在出现这种情况的时候,首先考虑能不能重构代码,优化接口,除非是双方都不太容易修改的情况下,才考虑使用该模式。如果需要使用第三方的开发组件,和我们自己系统的接口不同,而我们也完全没必要为了迎合它而改动自己的接口。此时可以考虑适配器模式来解决问题。
文章拓展资料
- C#文章集合:更全面的C#知识点文章
- 【设计模式】C#实现行为型模式之-观察者模式:常用的观察者模式实现