适配,即在不改变原有实现的基础上,将不兼容的接口转换为兼容的接口。
将一个类的接口转换成客户程序希望的另一个接口;Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
两种结构“对象适配器”和“类适配器”
interface IStack//客户期望的接口 { void Push(object item); object Pop(); Object Peek(); }
1、对象适配器(推荐)
class Adapter : IStack//适配对象 { ArrayList adpatee;//被适配的对象 AnotherType adpatee2;//被适配的对象 public Adapter() { adpatee = new ArrayList(); } public void Push(object item) { adpatee.add(item); } object Pop() { return adpatee.RemoveAt(adpatee.Count - 1); } object Peek() { return adpatee[adpatee.Count - 1]; } }
2、类适配器(违背了一个类的职责,不是松耦合的解决方式,不提倡)
class Adapter : ArrayList, IStack//适配对象 { public void Push(object item) { this.add(item); } object Pop() { return this.RemoveAt(adpatee.Count - 1); } object Peek() { return this[adpatee.Count - 1]; } }
3、灵活的结构:
Adapter模式可以实现的非常灵活,例如,完全可以将Adapter模式中的“现存对象”作为新的接口方法,来达到适配的目的。
class ExistingClass { public void SpecificRequest1() { } public void SpecificRequest2() { } } //新环境所使用的接口 interface ITarget { void Request(); } //另外一个系统 class MySystem { public void Process(ITarget target) { } } class Adapter : ITarget { ExistingClass adaptee; public void Request() { adaptee.SpecificRequest1(); adaptee.SpecificRequest2(); } }
4、例子:
集合类中对现有对象的排序(Adapter变体):现有对象未实现IComparable接口,实现一个排序适配器(继承IComparer接口),然后在其Compare方法中对两个对象进行比较。
class Employee { int age; string name; public int Age { get { return this.age; } set { this.age = value; } } public string Name { get { return this.name; } set { this.name = value; } } } class EmployeeSortAdapter : IComparer { public int Compare(object obj1, object obj2) { if (obj1.GetType() != typeof(Employee) || obj2.GetType() != typeof(Employee)) { throw new Exception(); } Employee e1 = (Employee)obj1; Employee e2 = (Employee)obj2; if (e1.Age == e2.Age) { return 0; } else if (e1.Age > e2.Age) { return 1; } else { return -1; } } } class App { public static void Main() { Employee[] employees = new Employee[100]; //... Array.Sort(employees, new EmployeeSortAdapter()); } }
要点:
1、Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用、类库适移等方面非常有用;
2、对象适配器采用“对象组合”的方式,更符合松耦合精神;类适配器采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用;