轉載]深入瞭解WPS中的業務對象Business Object

[轉載]深入瞭解WPS中的業務對象Business Object
2007-01-15 10:38:33
IBM推出的WPS (WebSphere Process Server)產品,主要用於企業業務整合,業務整合又包括服務整合和數據整合。WPS中的SCA(Service Component Architecture)組件用於服務整合(本系列安排有專門章節介紹),而BOF(Business Object Framework)組件就是用於業務數據整合(本章介紹)。在WPS中,業務數據在服務之間的流動,WPS用BPEL(Business Process Execution Language)的BPC(Business Process Choreographer)組件來管理和執行(有專門章節介紹)各種服務並串連其成爲一個整體。
 
本章所介紹的BO(Business Object)組件描述了業務數據的結構並提供了一系列的服務使業務數據可以在服務之間傳輸、轉換和映射。SOA(Service Orient Architecture)的號角很早就已經吹起了,如果說EMF(Eclipse Model Framework)是對SOA一個響應,那WPS則是對SOA的全面的擁抱,現在我們可以部署一個在SOA標準基礎上的整合應用程序到WPS上。很多人相信SOA就是替代面向對象編程的下一代編程模型。讓我們從瞭解BOF開始,通過本文讀者將瞭解業務對象與服務數據對象(SDO)的概念,二者之間的區別,以及運行原理和實現方法,並通過一個實際的例子來掌握其具體應用。

技術術語表:
 
1什麼是WPS和BOF
WPS(WebSphere Process Server)是一個從企業業務整合概念,應用服務器技術以及最新的開放標準中發展出來的下一代企業應用整合服務器。WPS支持SOA的架構,是一個需要整合使用不同技術的企業應用程序的理想平臺。使用Websphere Integration Developer工具可以輕而易舉地使用很簡單的整合機制創建出企業整合解決方案。如上所述,WPS是用於企業的業務整合,而業務整合的關鍵是數據整合。BOF就是設計用來做數據整合的。

分佈在不同的應用程序中的數據結構差異巨大。這些差異各自有各自的存在的理由,應用程序構建在上面,已經運行很久,很難改變。把他們整合起來,絕非易事。而且,面向服務的架構又要求數據通用,能被每個服務所理解,可靠性要強。我們把一些要求羅列一下:
靈活,強大,能表達任意的數據結構
·自解釋,數據能告訴服務自身的結構
·自恢復,數據能記憶自己被更改的狀況
·容易傳輸,數據需要在各個服務之間流動

IBM和Bea一起制定的SDO(Service Data Object)規範可以滿足以上要求。目前SDO作爲WebSphereApplication Server的一部分已經集成在WPS中,它提供了一個簡化了的J2EE數據應用開發的模型,SDO的實現包含在EMF中。EMF是構建數據模型的工具。可以把SDO理解爲EMF所建的一個模型。EMF在WPS產品中作用巨大。比如SCA的數據模型就是使用EMF建立。數據模型一旦建立,運行時和可視化工具使用同一套數據模型,有效的保證了數據的一致性。這一點在BO的設計工具和運行時裏也有所體現。

SDO作爲一個規範,界定了SDO的數據模型,並沒有提供相關的服務來創建SDO。從SDO的規範裏我們可以看到DataObject把自身的創建交給了DataGraph,DataGraph把創建交給了Mediator(比如JDBCMediator或XMLMediator等)。交給Mediator後,就得期待各數據廠商的實現了。

Business Object Framework在WPS中,作爲SDO的一種增強是建立在SDO的EMF實現之上的,並且由於它是SOA的一部分而成爲了WPS的核心組建之一。BOF的數據模型直接使用SDO。此外BOF還提供一些服務來創建、操縱Business Object以及Business Graph。
一個Business Object(BO)是一組屬性的集合,用來表達一個業務實體、一個對數據的操作和處理數據的流程。整合應用程序的組件則使用BO來交換數據和觸發事件。
 
2 BOF的詳細介紹
 
2.1 SDO的編程模型
SDO規範的最高版本是2.0。之前的版本是1.0。SDO 1.0在EMF中有完整的實現。SDO 2.0 在EMF中的實現還不完整。因此有必要兩者都瞭解一下。瞭解更多細節解請參閱SDO 1.0 和2.0規範。這兩個模型都列在下面。讀者先看一下。

圖表1 SDO 1.0編程模型

圖表2 SDO 2.0編程模型
SDO裏主要有三個概念:DataMediatorService(SDO 1.0)或DataAccessService(SDO 2.0),DataGraph和DataObject。在SDO 1.0中的DataMediatorService,到SDO 2.0變成了DataAccessService。
 
DataMediatorService在SDO1.0中定義爲一個java class。這個java class提供API去從數據源加載DataGraph,並可以把DataGraph存儲到數據源裏去。這裏"數據源"是一個寬泛的定義,比如,如果數據源是一個XML文件,那DataMediatorService就需要把數據從XML文件讀出,生成一個DataGraph返還用戶,在用戶修改過提交後,DataMediatorService能把DataGraph存入一個XML文件;如果數據源是一個JDBC數據源,那DataMediatorService就需要在數據庫中把數據讀出,生成DataGraph返回給用戶,在用戶做了一番修改提交給DataMediatorService後,能把用戶修改過的DataGraph存到數據庫中。在存儲過程中,由於ChangeSummary裏包含了用戶修改的情況,DataMediatorService有能力根據ChangeSummary進行存儲。如果用戶根本沒改,DataMediatorService可以什麼都不做。DataMediatorService以無連接的方式操作數據源。

DataAccessService在SDO 2.0中定義爲一個組件。這個組件的功能和SDO 1.0中DataMediatorService一致,但範圍廣了些。比如SessionBean,WebService儘管不是一個java class,也可以作爲DataAccessService出現。DataGraph裏包含兩個東西,一個是DataObject,一個是ChangeSummary。DataObject裏是具體的數據,DataObject提供各種操縱數據的API。ChangeSummary記錄數據的改動並提供API讓調用者知道都有哪些改動。

在SDO 1.0中,DataGraph由DataMediatorService創建。而在SDO 2.0中,DataAccessService創建的是DataObject。讀者可以思考一下這個改變的利弊。這裏不打算做更深入的探討。

另外較之於SDO 1.0,SDO 2.0還提供了一些接口和幫助類:
·DataFactory - 創建DataObject。
·TypeHelper -查找,定義新的DataObject類型。
·CopyHelper - DataObject的拷貝,分深拷貝和淺拷貝。
·EqualityHelper - DataObject的比較,分深比較和淺比較。
·XMLHelper - DataObject的序列化
·XMLDocument -DataObject的序列化
·XSDHelper -創建額外信息如果DataObject類型是XSD類型。
·DataHelper -提供DataObject使用的一些數據。
·HelperProvider -提供上面的幫助類。幫助幫助類的幫助類。
這些接口或幫助類在EMF的SDO實現中還沒完全實現。但在BOF中會看到一些幾乎同名的服務,這些服務實質上這些接口和幫助類的實現。因此這裏不做深入探討。

下面是一個簡單的例子。在這個例子裏,方法createDataGraph擔當DataAccessService的角色(沒實現save),負責創建一個DataGraph。之後我們利用創建出的DataGraph,探討SDO的以下性質:
·DataGraph, DataObject和ChangeSummary的關係。
·ChangeSummary的使用。
·DataObject操作數據的API。
這個DataGraph有一個根DataObject,類型爲Employee。下圖是Employee的數據結構。
圖表3 Employee的數據結構

Employee的數據結構比較簡單,因爲這裏不打算討論SDO對XPath的支持。希望讀者能修改這個例子,去學習SDO更多的特性。具體的代碼見資源列表。
第1行用DataAccessService創建了一個DataGraph。這裏的DataAccessService就是方法createDataGraph了。方法createDataGraph使用了EMF的一些API。不感興趣的讀者可以跳過。但是鑑於SDO實現和EMF的密切關係,以及EMF技術本身的魅力,建議讀者也認真學習一下EMF。
第2行打開ChangeSummary的logging開關。ChangeSummary記錄改變需要佔用一定的資源。因此默認情況下logging是關閉的。
第3-6行創建rootDataObject,並加了些數據進去。
第7-10行展示了取從DataObject數據的方法。無論什麼類型的數據,都可以用get方法去。寫數據的時候也都可以用set方法。
第11行展示了從DataObject取ChangeSummary的一個方法。先得到DataGraph,然後從DataGraph得到ChangeSummary。
第12行告訴ChangeSummary結束記錄。
第13-23行展示了ChangeSummary的使用。其中,第17行表明,DataObject可以通過getType知道自己的類型。

本例的輸出:
mike
1000000
Jone
Employee is created.
 
2.2 Business Object Framework(BOF)介紹
SDO是一個規範。規範可以暫時沒有實現。比如SDO 2.0就沒有完全實現。但BOF不同,BOF是個產品。沒有實現的產品是不現實的。但BOF基於SDO的EMF實現而做。BOF提供一組服務,和SDO 2.0中定義的一系列幫助類相呼應;同時BOF使用EMF SDO 1.0實現的數據模型;成功解決了這個問題。我們從兩個面探討BOF。一個是BOF數據模型,一個是BOF服務。

BOF數據模型
BOF裏的數據模型的建立綜合考慮了SDO的數據模型和ICS裏BO的數據模型。分三部分講述:BusinessObject,Business Graph和Business Object Type Metedata。
·Business Objects
就是SDO裏的DataObject。但考慮了和之前產品ICS裏BO業務數據部分的兼容問題。
·Business Graphs
就是SDO裏的DataGraph。但考慮了和之前產品ICS的兼容問題。因此Business Graph裏除了有ChangeSummary外,還添加了ICS BO中的Verb等信息。
·Business Object Type Metadata
是可以添加在business object定義文件中增強其在WPS中價值的原數據。這些原數據片斷用xs:annotation和xs:appinfo添在在business object的XML定義文件中。

BOF服務
BO Framework爲我們提供了許多服務:
·BOChangeSummary
提供SDO 1.0 ChangeSummary的增強接口,用於管理Business Graphs中的ChangeSummary頭。
·BOCopy
方便用戶拷貝一個Business Object或者包含Business Objects的Business Graph的服務。
·BODataObject
增強了SDO 1.0 Data Object接口。
·BOEquality
提供一個比較兩個Business Graph或者Business Object是否相等的接口。
·BOEventSummary (described above)
提供一個管理Business Graph中Event Summary頭的接口。
·BOFactory
提供接口創建一個Business Graph或者Business Object。
·BOType
提供一個獲取Business Graph的SDO Type或者Business Object影射的Java類名稱。
·BOTypeMetadata (described above)
提供一個讀取依照BO Type 原數據模型的注視塊的接口,並且把它轉換/反轉換爲一個DataObject。
·BOXMLDocument/BOXMLSerializer
提供創建表達一個內存中的Business Object的XML文檔的接口,支持序列化與反序列化。
 
3 BO的應用
 
3.1 業務需求
這一節中,將用一個實例說明BO的應用,這裏假設有一業務需求:訂單和物品,訂單中可以有很多物品,每一個物品都有自己的ID,名稱,單價和數量,而訂單有自己的ID,編碼,總價。訂單在傳輸過程中經歷瞭如下操作,先創建一個訂單實例,在這個訂單實例中添加了兩個物品,並且計算了訂單的總價,但是在傳送走後發現訂單的代碼被改動過了,需要重新找回原來的訂單代碼,最後這個訂單實例被序列化並存儲。
 
3.2 用WID開發具體的BO及相關組件
WID(WebSphere Integration Develpor)是WPS開發的工具,我們可以在WID中非常方便地開發BO的定義。
首先,在WID中的Business Integration視圖中建立一個Module,名稱是:Purchase。其次,在新建的Module上單擊右鍵,選擇New->Business Object,新建一個名叫Purchase的Business Object,按照此步驟,分別創建Purchase BO和Item BO,如圖所示:
圖表4,Purchase和Item BO的定義
 
在創建過程中需要注意的是如何創建樹組,例如Purchase中的items元素就是一個樹組,我們需要在屬性中將Array的複選框鉤上,這樣items就成爲了一個數組,如圖所示:
圖表 5,items的數組定義
 
那麼如何創建BG呢?
在左側的Business Integration視圖中,右建點擊PurchaseBO,在菜單中選擇Create a Business Graph,WID會自動爲我們創建一個標準的Business Graph,並且使用和BO相同的命名空間:
圖表 6,Purchase和PurchaseBG

3.3 BO的調試和運行
WID是一個集成的開發環境,爲我們提供了良好的對WPS6.0的支持,BO可以在WPS6.0下運行,但是同時也提供了一個輕量級的J2SE的調試環境,我們可以使用J2SE來測試我們的BO。在WID中,我們可以任意創建一個可以運行的Java類來運行BO,下面是一些BOF服務的使用方法,我們將具體介紹每一個服務的調用方法和功能,讀者可以比較一下SDO相應接口的調用方式。
 private BOChangeSummary getBOChangeSummary(DataObject purchaseBG) {
  BOChangeSummary change = (BOChangeSummary) ServiceManager.INSTANCE
    .locateService("com/ibm/websphere/bo/BOChangeSummary");
  return change;
 } 
獲取BOChangeSummary服務,用於管理BG中ChangeSummary的內容,利用ChangeSummary,我們可以保存一組BO的初始值。
 private DataObject createBO(String string, String string2) {
  BOFactory bof = (BOFactory) ServiceManager.INSTANCE
    .locateService("com/ibm/websphere/bo/BOFactory");
  return bof.create(string, string2);
 }
 private DataObject createByType(String string, String string2) {
  BOType botype = (BOType) ServiceManager.INSTANCE
    .locateService("com/ibm/websphere/bo/BOType");
  Type type = botype.getType(string, string2);
  BOFactory bof = (BOFactory) ServiceManager.INSTANCE
    .locateService("com/ibm/websphere/bo/BOFactory");
  return bof.createByType
(type);
 } 
BOF服務提供了許多創建BO的方式,我們可以通過BO定義中的TargetNameSpace和TypeName創建BO,可以通過SDO的Type定義來創建BO,並且BOF還支持從WSDL的Message中創建BO。
 private DataObject retrieve(DataObject purchase) {
  ByteArrayOutputStream bos = new ByteArrayOutputStream();
  BOXMLSerializer serializer = (BOXMLSerializer) ServiceManager.INSTANCE
    .locateService("com/ibm/websphere/bo/BOXMLSerializer");
  BOXMLDocument doc = serializer.createXMLDocument(purchase,
    "abc.com/PurchaseRetrieve", "Retrieved");
  try {
   serializer.writeXMLDocument(doc, bos);
  } catch (IOException e) {
   e.printStackTrace();
  }
  ByteArrayInputStream in = new ByteArrayInputStream(bos.toByteArray());
  try {
   doc = serializer.readXMLDocument(in);
  } catch (IOException e1) {
   e1.printStackTrace();
  }
  return doc.getDataObject();
 } 
BO支持序列化和反序列化,可以輕易地將BO的Java實例轉換爲一個XML文件或者一個流保存起來,並且在需要的時候,將這個BO從XML或者流中轉換回一個Java實例。
 private BOEventSummary getBOEventSummary(DataObject purchaseBG) {
  BODataObject boe = (BODataObject) ServiceManager.INSTANCE
    .locateService("com/ibm/websphere/bo/BODataObject");
  return boe.getEventSummary(purchaseBG);
 } 
BOF服務提供了對BG中EventSummary進行操作的服務,BOEventSummary,我們可以對某一BO設置其Event和ObjectEventID。
 private void endLogging(DataObject purchaseBG) {
  ChangeSummary chs = (ChangeSummary) purchaseBG.get("changeSummary");
  chs.endLogging();
 }
 private void beginLogging(DataObject purchaseBG) {
  BOChangeSummary changes = (BOChangeSummary) ServiceManager.INSTANCE
    .locateService("com/ibm/websphere/bo/BOChangeSummary");
  changes.beginLogging(purchaseBG);
 }
BeginLogging和EndLogging是一對操作,BOF會將在beginLogging之前BO的值保存在ChangeSummary中。
 private boolean isEqual(DataObject copyofpurchase, DataObject purchase) {
  BOEquality boe = (BOEquality) ServiceManager.INSTANCE
    .locateService("com/ibm/websphere/bo/BOEquality");
  return boe.isEqual(copyofpurchase, purchase);
 } 
使用BOF提供的BOEquality服務可以很容易地比較兩個複雜的BO是否相同,這裏需要區分isEqual方法和isEqualShallow方法的區別,前者會整個比較BO中所有的內容,包括子BO中的內容,isEqualShallow則直比較BO中簡單類型是否相等。
 
private DataObject copy(DataObject purchase) {
  BOCopy bocopy = (BOCopy) ServiceManager.INSTANCE
    .locateService("com/ibm/websphere/bo/BOCopy");
  return bocopy.copy(purchase);
 } 
BOCopy服務可以幫助用戶將一個BO的實例拷貝成爲另一個BO的實例,兩個實例完全一致,這裏同樣有兩個方法copy和copyShallow,copyShallow將只會拷貝BO中的簡單類型,這裏還有一對方法copyInto和copyPropertyInto,前者將BO拷貝到另外的一個BO中作爲子BO,後者可以拷貝BO中的某個屬性。以上完整的代碼請參看附件中的源文件
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章