熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

實現Java抽象工廠模式

2013-11-23 19:52:03  來源: Java高級技術 

  了解模式需要研究客戶端程序(使用模式者)和模式的內部結構並且理解兩者之間的通信接口模式本身因功能增加造成的變動(易碎性)以及客戶端程序利用新功能的難易程度本文針對這些問題提出了一個具體的抽象工廠模式實現方案
  模式結構介紹
  這個模式由一個工廠類層次和N個產品類層次組成從每一個產品類層次中取出一個產品類形成產品類族這個類族的實例為產品族產品族中的產品之間有一種依賴關系一個具體的工廠類負責創建產品族中的各個產品
  從圖可以看出通信接口由一個抽象工廠接口和兩個抽象產品組成模式部分顯示了兩個產品類 ProductA 和ProductB兩個產品類族ProductAProductB和ProductAProductB以及兩個產品類族對應的兩個工廠ConcreteFactoryConcreteFactory
   
  圖 標准抽象工廠模式
  從模式定義中知道這個模式的意圖內容為
  提供一個創建一系列相關或相互依賴對象的接口而無需指定它們具體的類工廠類層次的通信接口只有抽象工廠和創建產品族的各個工廠方法這些工廠方法不帶任何參數並且返回具有抽象產品類型的具體產品實例這些使得客戶端可以不依賴具體產品的類從而體現了模式的意圖意圖中的而無需指定它們具體的類可以理解為客戶端在使用和創建具體產品時不給出具體產品的任何暗示
  變動
  我們分析模式的變動時必須先固化模式和客戶端間的通信接口即通信接口是固定不變的分析變動就是分析模式的易碎性(模式實現適應變動的能力)對抽象工廠模式可以考慮兩個變動
   加一個產品類族
   加一個產品類
  變動一的易碎性較小我們只需在每個產品類層次中增加這個產品族中產品類作為抽象產品類的子類同時增加一個工廠子類來創建這個產品類族的產品族足以
  變動二要求在模式中增加一個產品類意味著增加一個產品類層次由於通信接口中的工廠方法固定了客戶能創建的產品的類型數目所以增加一個產品類意味著修改與客戶端的通信接口進一步意味著舊的客戶端要使用新的模式實現就要重新編碼整個工廠類層次都需要改動綜合上述這個變動的易碎性很大
  設計
  程序架構
  一個程序可以從三個維度進行架構這三個維度是層級和服務層代表了不同的抽象程度比如操作系統的分層級代表不同的角色和職責比如Client/Server的兩級模型服務代表了具有通用功能的支持模塊
  實現一個模式從級這個維度來講可以簡單地分成兩級即客戶端和模式端從服務維度講模式可以利用某些服務如事務名字和目錄服務安全等服務器提供商開發的設施服務模式本身也可以實現成供客戶端訪問的服務從而形成應用服務典型的有EJB組件應用程序的開發從層上考慮的比較少體現了實現抽象工廠模式的程序架構
   
  圖 程序架構
  JNDI
  JNDI是Java Naming and Directory Interface的簡寫即Java命名和目錄服務接口這個接口是名字和目錄服務通用編程的API
  命名服務是一個系統基礎設施給對象綁定一個名字並能通過名字找到對象的機制這個名字一般是面向使用者的類似的服務實現有因特網域名系統(實現通過域名www 找到IP地址的手段)文件系統(實現通過文件名找到文件的手段)等
  目錄服務是名字服務的擴展除了提供名字綁定之外還允許對象擁有屬性目錄服務中的對象為目錄對象和圖分別表示了名字服務和目錄服務的概念定義
   
  圖 名字服務的概念
   
  圖 目錄服務的概念
  一個名字系統由相互聯系的一系列上下文組成上下文是名字與對象的綁定集合相互聯系的一組上下文能形成一個層次結構一個名字系統中所有的名字組成了這個系統的命名空間而且命名空間有它自己的命名規范一個目錄庫由一系列目錄對象組成每個目錄對象可以有若干個屬性相連
  JNDI架構如圖其中JNDI SPI為服務提供者接口LDAPDNSNIS等為服務提供者JNDI API為客戶程序使用服務的編程接口
   
  圖 JNDI架構
  JNDI Java包JDK和後續版本已經包含了JNDI另外還有幾個服務提供者如LDAPCOS和RMI其他的服務提供者可以從下載JNDI分為五個包javaxnaming javaxnamingdirectory javaxnamingevent javaxnamingldap 和javaxnamingspi 一般情況下只需要前三個包名字和目錄操作都是針對一個上下文來說的但是沒有絕對根的上下文所以就用一個初始上下文 InitialContext作為名字和目錄操作的起點一旦有了這個上下文就可以用它來查找其它上下文和對象下面是進行名字操作和目錄操作初始上下文類的關系
   
  使用JNDI在模式的實現中我們可以用名字服務來實現子類的配置也就是說在名字服務中指定子類的名字由模式讀取這個子類配置並創建一個子類實例返回給客戶端客戶端用抽象父類來返回子類實例通過這種機制實現針對接口編程而不是實現的重用的面向對象設計的原則
  Singlton模式的實現可以利用JNDI名字服務來實現在名字服務中存放Singlton模式中的惟一實例使用者要使用這個實例可以使用JNDI編程接口查詢這個對象我們的工廠類對象的產生就可以采用這個方法
  類圖設計
  目前沒有較好的辦法解決增加產品類帶來的舊客戶程序不能透明地使用新產品類的方案如果能忍受這一點這個變動的其它影響還是可以解決的為一個基於Class第一類對象的Java抽象工廠的模式變體結構圖由此可以看出抽象工廠不僅是接口還是具體完成創建工作的類它只有一個工廠方法以抽象產品的類名為參數以Java類庫的最頂層類Object為返回值客戶端把通信接口抽象產品類名傳給這個工廠方法接著通過一個強制類型轉換而得到抽象產品對象命名服務實現產品類族中每個產品類名到具體產品類名的映射通過這樣一系列的映射定義了每一個具體工廠類要創建的產品類族
   
  圖 抽象工廠模式變體類結構圖
  圖中還顯示了編寫單元測試用例的類UnitTest和實用類SerObj
  實現工廠通信接口的設計
  .客戶端代碼如下
  Factory factory = Factory getInstance 
  ( ldap://localhost:/ dc = pattern dc = com ) ;
  AbstractProductA productA = factory CreateProduct
  ( AbstractProductA的完全類名 );
  名字服務包含Factory的名字到工廠類對象的綁定整個機制如圖
   
  圖 工廠類的Singleton設計
  .單元測試代碼如下
   
  .實現工廠Singlton模式的代碼如下:
   
   
  .具體的工廠方法代碼如下
  
  public class Factory implements javaioSerializable {
  
   /**
  接受抽象產品類的完全類名查詢目錄服務得到具體產品類的完全類名采用JAVA的CLASS為第一類對象的機制創建相應類的對象
  */
   public Object createProduct(String vstrClassName ){
   Context ctx = null;
   String strEntryName;
   String strEntryClassName;
   Object oResult = null;
   try{
  ctx = getInitialContext ( ) ;
  strEntryName = cn= + vstrClassName;
  strEntryClassName = ( String )ctxlookup ( strEntryName ) ;
  try {
  Class clTem;
  clTem = ClassforName ( strEntryClassName ) ;
  oResult = clTemnewInstance ( ) ;
  }
  catch ( Exception ex ) {
  loggererror ( extoString ( ) );
  }
   }
   catch ( NamingException e ) { }
   finally{
  try{
  ctxclose ( ) ;
  }
  catch ( Exception e ) { }
  }
  return oResult;
   }
  
   }
  實現產品通信接口的設計
  抽象工廠模式的本意要求我們創建具體產品對象時客戶端不能暗示任何具體產品對象類型的信息但是通過分析模式的通信接口可知客戶端可以告訴工廠類這些具體產品的父類關於模式提到創建一些互相依賴的對象的本意我們可以在目錄服務的目錄庫中實現分別定義了這樣的產品族關系
   
  圖 目錄服務產品族的配置
  
  圖 目錄服務產品族的配置
  .圖表示在工廠類的工廠方法要求創建產品族可以在目錄服務中指定抽象產品的完全類名綁定到產品族的相應類名上
  
  ()單元測試代碼如下
  
  public class UnitTest extends TestCase{
  
   public void testProduct ( ) {

From:http://tw.wingwit.com/Article/program/Java/gj/201311/27592.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.