業務對象
對數據進行檢索和處理的組件
業務對象(Business Object,BO)是對數據進行檢索和處理的組件。是簡單的真實世界的軟體抽象。業務對象通常位於中間層或者業務邏輯層。
業務對象(Business Object)是由第三方開發的,在GeneXus 社區內可獲得的知識對象。用其可以在一個應用中自動的加入一個特定的功能來獲得增值效應。使知識重用變為可能。比如,如果你要開發一個包含多貨幣處理的應用,你可以選擇使用一個已經開發完成的,包含所有多貨幣處理功能的業務對象來開始你的開發。使您的開發工作極大的減少。 Remote Data Service 提供默認的中間層業務對象 RDSServer.DataFactory,用於接收客戶端請求並提供對指定數據源的讀寫訪問,但不包含任何驗證或業務規則邏輯。
用戶可以創建能夠提供與 RDSServer.DataFactory 功能相同的自定義業務對象,並且對應用程序的業務規則進行封裝。
1,由狀態和行為組成
2,表達了來自業務域的一個人,地點,事物或概念
3,可以重用
1.實體業務對象:
表達了一個人,地點,事物或者概念。根據業務中的名詞從業務域中提取的。如客戶,訂單,物品。在EJB應用程序中,一般為實體Bean.在傳統的web應用程序中,可能是包含業務應用的狀態和行為的普通javabean.
2.過程業務對象:
表達應用程序中業務處理過程或者工作流程任務。通常依賴於實體業務對象,是業務的動詞。在EJB應用程序中,通常是模型的會話bean,或者消息驅動bean.在非EJB應用中,可能是javabean,包含特定的行為,作為應用程序的管理者或者控制者.
3.事件業務對象:
表達應用程序中由於系統的一些操作造成或產生的一些事件.
業務對象的抽象和整合有何聯繫呢,或許有人會問我這樣的一個問題(以前的我也老想著這個問題),就這個問題我個人覺得,如果脫離業務抽象而想象一個架構體系,那麼是一個本末倒置的愚蠢的做法,因為只有做了一個業務的抽象才能根本上滿足需求本質,這樣才能更實際的充分的得到現實業務現象的抽象才能合理有效的模擬實現的IT系統(一個IT化的過程第一步驟)。
整合IT系統面臨一個很大問題如何抽象IT系統的交互問題,這個方面IBM採取了消息通信的抽象;它這樣做當然有他的道理(也是比較接近現實場景的),但是我在這裡順便提一下我個人的想法,消息其實只是通信和協調的一個實現而已,但是還沒有到本質;本質就是通信的協議的定製。我自己採取的就是在底層使用一個會話協議抽象(工作的保密關係不能再細說了,但是我的實踐告訴我這樣做有很高的架構體系擴展上,大家有機會可以試一試)。
所以業務抽象十分重要,只有把握好這一點,你的架構系統將體現更高的架構體系高度。你會發現需求的現象的本質,已經沒有太多的需求變動能破壞你的架構還沒有把握業務的本質)。
這一節中,將用一個實例說明BO的應用,這裡假設有一業務需求:訂單和物品,訂單中可以有很多物品,每一個物品都有自己的ID,名稱,單價和數量,而訂單有自己的ID,編碼,總價。
訂單在傳輸過程中經歷了如下操作,先創建一個訂單實例,在這個訂單實例中添加了兩個物品,並且計算了訂單的總價,但是在傳送走後發現訂單的代碼被改動過了,需要重新找回原來的訂單代碼,最後這個訂單實例被序列化並存儲。
WID(WebSphere Integration Develpor)是WPS開發的工具,我們可以在WID中非常方便地開發BO的定義。
首先,在WID中的Business Integration視圖中建立一個Module,名稱是:Purchase。
其次,在新建的Module上單擊右鍵,選擇New->Business Object,新建一個名叫Purchase的Business Object,按照此步驟,分別創建Purchase BO和Item BO,如圖所示:
Purchase BO和Item BO
在創建過程中需要注意的是如何創建數組,例如Purchase中的items元素就是一個數組,我們需要在屬性中將Array的複選框鉤上,這樣items就成為了一個數組,如圖所示:
數組
那麼如何創建BG呢?
在左側的Business Integration視圖中,右建點擊PurchaseBO,在菜單中選擇Create a Business Graph,WID會自動為我們創建一個標準的Business Graph,並且使用和BO相同的命名空間:
Purchase和PurchaseBG
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中的某個屬性。