适配器,在不改变原有实现的基础上,将原先不兼容的接口转换为兼容的接口
Motivation
在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的。
意图(Intent)
将一个类的接口转换成客户希望的另一个接口。
Adapter模式使得原本由于接口不兼容而不能一起工作的那些类一块工作
Adapter模式的几个要点
Adapter模式主要应用于“希望复用一些现存的类”,但是接口又与复用环境要求不一致的情况,在遗留代码复用。类库迁移等方面非常有用
两种实现接口:对象适配器和类适配器。
类适配器采用多继承的实现方式,带来了不良的高耦合,不建议使用
对象适配器采用“对象组合”的方式,更符合松耦合精神
Adapter模式本身要求我们尽可能使用“面向接口的编程”便于后期维护
.NET框架中的Adapter应用
1.在.NET中复用com对象
-COM对象不符合.NET对象的接口
-使用tlbimp.exe来创建一个Runtime Callable Wrapper(RCW)以便使符合.NET对象的接口
2.NET数据访问类(Adapter变体):
-各种数据库并没有提供DataSet接口
-使用DbDataAdapter可以讲任何各数据库访问/存取适配到一个DataSet对象上。
3.集合类中对现有对象的排序(Adapter变体)
-现有对象未实现IComparable接口
-实现一个排序适配器(继承IComparerable接口),然后再Compare方法中对两个对象进行比较。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //客户期望的接口 2 public interface IStack 3 { 4 void Push(object item); 5 void Pop(); 6 object Peek();//只取出顶上的对象 7 } 8 ////对象适配器 更多使用这个 9 //class MyStack:IStack//适配器 10 //{ 11 // ArrayList list;//被适配的对象 12 // public MyStack() 13 // { 14 // list = new ArrayList(); 15 // } 16 // public void Push(object item) 17 // { 18 // list.Add(item); 19 // } 20 // public void Pop() 21 // { 22 // list.RemoveAt(list.Count - 1); 23 // } 24 // public object Peek() 25 // { 26 // return list[list.Count - 1]; 27 // } 28 //} 29 30 //类适配器 31 32 //C++可以实现类的多继承 类的可控性 33 //不建议:违反了单一原则 只能是单根继承 34 class MyStack : ArrayList, IStack//适配器 35 { 36 public void Push(object item) 37 { 38 this.Add(item); 39 } 40 public void Pop() 41 { 42 this.RemoveAt(this.Count - 1); 43 } 44 public object Peek() 45 { 46 return this[this.Count - 1]; 47 } 48 } 49 50 public class ExistingClass 51 { 52 public void SpecificRequest1() 53 { 54 } 55 public void SpecificRequest2() 56 { 57 } 58 } 59 //目标接口 新环境所使用的接口 60 public interface ITarget 61 { 62 void Request(); 63 } 64 public class MySystem 65 { 66 public void Process(ITarget target) 67 { 68 69 } 70 } 71 public class Adapter : ITarget 72 { 73 ExistingClass adaptee; 74 public void Request() 75 { 76 adaptee.SpecificRequest1(); 77 adaptee.SpecificRequest2(); 78 } 79 }