適配,即在不改變原有實現的基礎上,將不相容的介面轉換為相容的介面。
將一個類的介面轉換成客戶程式希望的另一個介面;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、對象適配器採用“對象組合”的方式,更符合松耦合精神;類適配器採用“多繼承”的實現方式,帶來了不良的高耦合,所以一般不推薦使用;