一、定義 將一個類的介面轉換成客戶希望的另一個介面。適配器模式讓那些介面不相容的類可以一起工作。適配器模式是一種結構型模式。 二、描述 包含以下三個角色: 1、Target(目標抽象類):目標抽象類定義了客戶所需要的介面,可以是一個抽象類或介面,也可以是一個具體的類,由於C#不支持多繼承,所以它只能 ...
一、定義
將一個類的介面轉換成客戶希望的另一個介面。適配器模式讓那些介面不相容的類可以一起工作。適配器模式是一種結構型模式。
二、描述
包含以下三個角色:
1、Target(目標抽象類):目標抽象類定義了客戶所需要的介面,可以是一個抽象類或介面,也可以是一個具體的類,由於C#不支持多繼承,所以它只能是介面。
2、Adapter(適配器類):它可以調用另一個介面,作為一個轉換器,對Adaptee和Target進行適配。適配器Adapter是適配者模式的核心,在適配器模式中,它通過繼承Target並關聯一個Adaptee對象使二者產生聯繫。
3、Adaptee(適配者類):適配者即被適配的角色,它定義了一個已經存在的介面,這個介面需要適配,適配者類一般是一個具體類,包含了客戶希望使用的業務方法,在某些情況下甚至沒有適配者類的源代碼。
三、例子
X公司很久以前曾經開發了一個演算法庫,包含了排序、查找等演算法。在為某學校開發教務管理系統時,開發人員設計了一個成績操作介面IScoreOperation,在該介面中聲明瞭排序方法Sort(int[])和查找方法Search(int[],int),但是為了提高排序和查找的效率,決定重用演算法庫中的快速排序演算法類QuickSort和二分查找演算法類BinarySearch。演算法庫已經沒有源碼了,需要在不改動兩邊代碼的情況下完成功能。IScoreOperation:抽象成績操作介面,充當目標抽象類
public interface IScoreOperation
{
int[] Sort(int[] array);
int Search(int[] array, int key);
}
QuickSortHelper、BinarySearchHelper:快速排序演算法類、二分查找演算法類,充當適配者類
public class QuickSortHelper
{
public int[] QuickSort(int[] array)
{
Sort(array, 0, array.Length - 1);
return array;
}
public void Sort(int[] array, int p, int r)
{
int q = 0;
if (p < r)
{
q = Partition(array, p, r);
Sort(array, p, q - 1);
Sort(array, q + 1, r);
}
}
public int Partition(int[] array, int p, int r)
{
int x = array[r];
int j = p - 1;
for (int i = p; i <= r - 1; i++)
{
if (array[i] <= x)
{
j++;
Swap(array, j, i);
}
}
Swap(array, j + 1, r);
return j + 1;
}
public void Swap(int[] array, int i, int j)
{
int t = array[i];
array[i] = array[j];
array[j] = t;
}
}
public class BinarySearchHelper
{
public int BinarySearch(int[] array, int key)
{
int low = 0;
int high = array.Length - 1;
while (low <= high)
{
int mid = (low + high) / 2;
int midVal = array[mid];
if (midVal < key)
{
low = mid + 1;
}
else if (midVal > key)
{
high = mid - 1;
}
else
{
return 1; // 找到元素返回1
}
}
return -1; // 未找到元素返回-1
}
}
OperationAdapter:成績操作類,充當適配器類
public class OperationAdapter : IScoreOperation
{
private QuickSortHelper sortTarget;
private BinarySearchHelper searchTarget;
public OperationAdapter()
{
sortTarget = new QuickSortHelper();
searchTarget = new BinarySearchHelper();
}
public int Search(int[] array, int key)
{
return searchTarget.BinarySearch(array, key);
}
public int[] Sort(int[] array)
{
return sortTarget.QuickSort(array);
}
}
Program:測試代碼
IScoreOperation operation = new OperationAdapter();
if (operation == null)
{
return;
}
int[] scores = { 84, 76, 50, 69, 90, 91, 88, 96 };
int[] result;
int score;
Console.WriteLine("測試成績排序結果:");
result = operation.Sort(scores);
foreach (int s in result)
{
Console.Write("{0},", s.ToString());
}
Console.WriteLine();
Console.WriteLine("查找是否有90分的人:");
score = operation.Search(scores, 90);
if (score == -1)
{
Console.WriteLine("抱歉,這個真沒找到~~~");
}
else
{
Console.WriteLine("恭喜,的確存在90分選手~~~");
}
Console.WriteLine("查找是否有92分的人:");
score = operation.Search(scores, 92);
if (score == -1)
{
Console.WriteLine("抱歉,這個真沒找到~~~");
}
else
{
Console.WriteLine("恭喜,的確存在92分選手~~~");
}
Console.ReadLine();
四、總結
1、優點
(1)將目標類和適配者類解耦,通過引入一個適配器類來重用現有的適配者類,無須修改原有結構。
(2)增加了類的透明性和復用性,將具體的業務實現過程封裝在適配者類中,對於客戶端類而言是透明的,而且提高了適配者的復用性,同一個適配者類可以在多個不同的系統中復用。
(3)靈活性和可擴展性很好,可以通過配置文件、反射機制等,配合增加或切換新的適配器,完全符合開閉原則。
2、缺點
(1)C#、Java等不支持多繼承,一次最多只能適配一個適配者類,不能同時使用多個。
(2)適配者類不能成為最終類,例如C#中不能為sealed類。
(3)C#、Java等類適配器模式中目標抽象類只能是介面,具有一定局限性。