不相容結構的協調——介面卡模式(二)
阿新 • • 發佈:2018-12-21
9.3 完整解決方案
Sunny軟體公司開發人員決定使用介面卡模式來重用演算法庫中的演算法,其基本結構如圖9-4所示:
圖9-4 演算法庫重用結構圖
在圖9-4中,ScoreOperation介面充當抽象目標,QuickSort和BinarySearch類充當適配者,OperationAdapter充當介面卡。完整程式碼如下所示:
//抽象成績操作類:目標介面interface ScoreOperation { public int[] sort(int array[]); //成績排序 public int search(int array[],int key); //成績查詢}//快速排序類:適配者 class QuickSort { 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[] a, int p, int r) { int x=a[r]; int j=p-1; for (int i=p;i<=r-1;i++) { if (a[i]<=x) { j++; swap(a,j,i); } } swap(a,j+1,r); return j+1; } public void swap(int[] a, int i, int j) { int t = a[i]; a[i] = a[j]; a[j] = t; }}//二分查詢類:適配者class BinarySearch { 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 }}//操作介面卡:介面卡class OperationAdapter implements ScoreOperation { private QuickSort sortObj; //定義適配者QuickSort物件 private BinarySearch searchObj; //定義適配者BinarySearch物件 public OperationAdapter() { sortObj = new QuickSort(); searchObj = new BinarySearch(); } public int[] sort(int array[]) { return sortObj.quickSort(array); //呼叫適配者類QuickSort的排序方法} public int search(int array[],int key) { return searchObj.binarySearch(array,key); //呼叫適配者類BinarySearch的查詢方法}}
為了讓系統具備良好的靈活性和可擴充套件性,我們引入了工具類XMLUtil和配置檔案,其中,XMLUtil類的程式碼如下所示:
import javax.xml.parsers.*;import org.w3c.dom.*;import org.xml.sax.SAXException;import java.io.*;class XMLUtil {//該方法用於從XML配置檔案中提取具體類類名,並返回一個例項物件 public static Object getBean() { try { //建立文件物件 DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dFactory.newDocumentBuilder(); Document doc; doc = builder.parse(new File("config.xml")); //獲取包含類名的文字節點 NodeList nl = doc.getElementsByTagName("className"); Node classNode=nl.item(0).getFirstChild(); String cName=classNode.getNodeValue(); //通過類名生成例項物件並將其返回 Class c=Class.forName(cName); Object obj=c.newInstance(); return obj; } catch(Exception e) { e.printStackTrace(); return null; } }}
配置檔案config.xml中儲存了介面卡類的類名,程式碼如下所示:
<?xml version="1.0"?><config> <className>OperationAdapter</className></config>
編寫如下客戶端測試程式碼:
class Client { public static void main(String args[]) { ScoreOperation operation; //針對抽象目標介面程式設計 operation = (ScoreOperation)XMLUtil.getBean(); //讀取配置檔案,反射生成物件 int scores[] = {84,76,50,69,90,91,88,96}; //定義成績陣列 int result[]; int score; System.out.println("成績排序結果:"); result = operation.sort(scores); //遍歷輸出成績 for(int i : scores) { System.out.print(i + ","); } System.out.println(); System.out.println("查詢成績90:"); score = operation.search(result,90); if (score != -1) { System.out.println("找到成績90。"); } else { System.out.println("沒有找到成績90。"); } System.out.println("查詢成績92:"); score = operation.search(result,92); if (score != -1) { System.out.println("找到成績92。"); } else { System.out.println("沒有找到成績92。"); } }}
編譯並執行程式,輸出結果如下:
成績排序結果: 50,69,76,84,88,90,91,96, 查詢成績90: 找到成績90。 查詢成績92: 沒有找到成績92。 |
在本例項中使用了物件介面卡模式,同時引入了配置檔案,將介面卡類的類名儲存在配置檔案中。如果需要使用其他排序演算法類和查詢演算法類,可以增加一個新的介面卡類,使用新的介面卡來適配新的演算法,原有程式碼無須修改。通過引入配置檔案和反射機制,可以在不修改客戶端程式碼的情況下使用新的介面卡,無須修改原始碼,符合“開閉原則”。