1. 程式人生 > >不相容結構的協調——介面卡模式(二)

不相容結構的協調——介面卡模式(二)

               

9.3 完整解決方案

      Sunny軟體公司開發人員決定使用介面卡模式來重用演算法庫中的演算法,其基本結構如圖9-4所示:

9-4  演算法庫重用結構圖

       在圖9-4中,ScoreOperation介面充當抽象目標,QuickSortBinarySearch類充當適配者,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;  }   elsereturn 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

       在本例項中使用了物件介面卡模式,同時引入了配置檔案,將介面卡類的類名儲存在配置檔案中。如果需要使用其他排序演算法類和查詢演算法類,可以增加一個新的介面卡類,使用新的介面卡來適配新的演算法,原有程式碼無須修改。通過引入配置檔案和反射機制,可以在不修改客戶端程式碼的情況下使用新的介面卡,無須修改原始碼,符合“開閉原則”。