模式定义
适配器模式(Adapter Pattern) :将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
UML类图
- 目标抽象类(Target)
- 适配器类(Adapter)
- 适配者类(Adaptee)
客户端(Client)
代码结构
public static class AdapteeApp { public static void Run() { Target target = new Adapter(); target.Request(); } } public class Target { public virtual void Request() { Console.WriteLine("Called Target Request()"); } } public class Adapter :Target { private Adaptee _adaptee = new Adaptee(); public override void Request() { _adaptee.SpecificRequest(); } } public class Adaptee { public void SpecificRequest() { Console.WriteLine("Called specificRequest()"); } }
情景模式
在开发中用到适配者模式,一般指引入第三方类库,切第三方类库的接口并非完全一直。这里以缓存操作为例,项目刚开始缓存存在内存,随着项目数据的增多决定引入Redis做缓存,然而Redis的缓存操作接口并非与本系统操作接口完全一致,这里通过适配者模式解决(这点也体现依赖倒置:高层不应依赖底层,应依赖接口)。
public static class AdapteeApp { public static void Run() { CacheManage cache1 = new DictionaryCache(); cache1.Set("name", "LoveTomato"); Console.WriteLine(cache1.Get("name").ToString()); CacheManage cache2 = new RedisCacheAdapter(); cache2.Set("name", "LoveTomato"); Console.WriteLine(cache2.Get("name").ToString()); } } public interface CacheManage { object Get(string key); void Set(string key, object value); bool IsExist(string key); void Remove(string key); void Clear(); } public class DictionaryCache : CacheManage { private Dictionary<string, object> _dic = new Dictionary<string, object>(); public void Clear() { _dic.Clear(); } public object Get(string key) { object obj = null; if (this.IsExist(key)) { obj = _dic[key]; } return obj; } public bool IsExist(string key) { bool b = false; if (_dic.Keys.Contains(key)) { b = true; } return b; } public void Remove(string key) { if (this.IsExist(key)) { _dic.Remove(key); } } public void Set(string key, object value) { _dic[key] = value; } } public class RedisCacheAdapter : CacheManage { private RedisCache redisCache = new RedisCache(); public void Clear() { redisCache.Empty(); } public object Get(string key) { return redisCache.Get(key); } public bool IsExist(string key) { return redisCache.IsSet(key); } public void Remove(string key) { redisCache.Delete(key); } public void Set(string key, object value) { redisCache.Set(key, value); } } public class RedisCache { public void Empty() { } public object Get(string key) { return null; } public void Set(string key, object value) { } public bool IsSet(string key) { return false; } public void Delete(string key) { } }