电竞比分网-中国电竞赛事及体育赛事平台

分享

SOA 建模: 第 4 部分 服務合成

 一輝 2008-06-17

2008 年 1 月 21 日

本文是本系列五篇文章中的第 4 篇,它的內容包括如何裝配和連接在“第 3 部分 服務實現”中建模的服務提供者,并且設計它們的交互作用,為業(yè)務需求提供一個完全的解決方案。最為結果的合成要素將成為一個服務參與者,它負責把由 Invoicer、Productions 和 Shipper 合成要素所提供的服務組合在一起,提供處理定購單的服務能力。本文還展示了這一服務參與者如何實現最初的業(yè)務需求。

關于本系列

在本系列前面的三篇文章中(請參見左上方的 “More in this series”),我們描繪出了識別那些同業(yè)務需求相連接的服務的一種方法的大致輪廓。我們首先捕獲實現業(yè)務任務所必須的業(yè)務目標。然后,對滿足這些目標所必須的業(yè)務操作和過程進行建模。接著,我們將業(yè)務過程作為一個幫助我們識別必需的服務以及它們之間潛在聯系的契約來使用。然后,我們完成了被識別服務的規(guī)范。

在本系列的第 1 篇文章第 1 部分 服務識別中,我們研究如何通過識別與業(yè)務相關的服務來將 SOA 解決方案的潛能最大化。我們設計基于業(yè)務需求的服務拓撲結構,并且將服務同服務解決方案必須實現的反映需求契約的服務協作連接起來。

在第 2 篇文章第 2 部分 服務規(guī)范 中,我們對服務規(guī)范的細節(jié)進行建模。服務規(guī)范定義了服務的潛在消費者需要知道的所有東西,以便他們決定是否有興趣使用該服務,以及如何使用該服務。它同樣指定了服務提供者必須知道的所有東西,以便他們成功地執(zhí)行該服務。

第 3 部分 服務實現中,我們對在服務提供者:Invoice、Productions 和 Shipper 中作為結果的服務規(guī)范的實現進行建模。每一個合成要素依照服務規(guī)范提供服務和功能。每一個被提供的服務操作都有一個描述服務如何真正執(zhí)行的方法。方法可以是任何的 UML 行為,包括 Activity、Interaction、StateMachine 或者 OpaqueBehavior。這由建模器來決定。

 

本系列的最后一篇文章“SOA 建模: 第 5 部分 服務實現”,使用 IBM? Rational? Software Architect UML-to-SOA 轉換特性來創(chuàng)建一個 Web 服務實現,它能夠在 IBM? WebSphere? Integration Developer 中直接被使用,從而實現、測試和配置完全的解決方案。

本文的內容

在本文中,我們將第 3 篇文章中創(chuàng)建的服務提供者集合在一起,以另一個服務提供者的方法來使用它們的功能。也就是說,我們將從其他服務的合成要素中創(chuàng)建一個新的服務。這一技術能夠被遞歸使用任意次,越過任何一個關注集和任何一個抽象層。然而,有可能存在許多體系結構的約束,對服務操作的粒度、安全性和執(zhí)行關注、數據交換量、以及有可能約束什么服務是由什么合成要素提供的寫級通訊協議和綁定問題。這些問題決定解決方案的體系結構,并且不在本系列這些文章的討論范圍之內。請參見 Design an SOA solution using a reference architecture 獲得關于這一重要課題的更多細節(jié)。

如同本系列中的所有文章一樣,我們將使用現有的 IBM? Rational? 和 IBM? WebSphere? 工具來建造解決方案,并且將它們鏈接到一起,從而我們能夠檢驗該解決方案是否符合需求和更加有效的管理變化。表1總結了我們開發(fā)例子將使用的全部過程,以及我們所使用的工具。


表1. 開發(fā)過程角色、任務和工具
角色 任務 工具
業(yè)務執(zhí)行官 傳達業(yè)務目標 IBM? Rational? RequisitePro?
業(yè)務分析師 分析業(yè)務需求 IBM? WebSphere? Business Modeler
軟件架構師 設計解決方案的架構 IBM Rational Software Architect
Web 服務開發(fā)人員 執(zhí)行該解決方案 IBM? Rational? Application Developer 和 WebSphere Integration Developer

服務實現回顧

我們首先回顧在前面的文章中被執(zhí)行的服務提供者。圖1顯示了 Invoicer 服務提供者。


圖 1. Invoicer 服務提供者
Invoicer 服務提供者

Invoicer 服務提供者為計算定購單的最初成本提供了 InvoicingProtocol,然后當運送信息得知以后重新定義這一價格。定購單的總價取決于產品是在哪里生產的,以及它們是從哪里運送的。最初成本的計算可能被用來檢驗消費者有足夠的信用或者仍然想要定購產品。在實現定購之前完成這一檢驗操作是最好的。

圖2顯示了 Productions 服務提供者。


圖 2. Production 服務拓撲結構
Production 服務拓撲結構

Productions 服務提供者提供 Scheduling 服務,決定產品在哪里被生產,以及如何何時被生產。這一信息能夠被用來創(chuàng)建運送時間表,這個表在處理定購單時使用。

圖3顯示了 Shipper 服務提供者。


圖 3. Shipper 服務提供者
Shipper 服務提供者

Shipper 服務提供者提供 ShippingService 服務,將產品運送到消費者來完成定購。該服務需要 ScheduleProcessing 接口來請求消費者處理完成的時間表。

服務合成

現在,服務已全部由一些提供者提供,我們已經準備好將這些提供者集合起來使用,實現最初的業(yè)務需求。這種集合根據業(yè)務需求來合成和設計服務,為 Purchasing 服務提供一種方法。我們將創(chuàng)建一個 OrderProcessor 合成要素,為處理定購單提供一個購買服務。這個服務提供者要求服務被 InvoicingService、Scheduling 和 ShippingService 服務規(guī)范定義。我們將創(chuàng)建一個 OrderProcessing 合成要素,它集合了 Invoicer、Productions 和 Shipper 合成要素的實例,以及 OrderProcessor 合成要素,從而執(zhí)行處理定購單的操作。

Order Processor 服務提供者

定購單處理服務由 Purchasing 服務規(guī)范指定(請參見圖4),該規(guī)范包括如下功能(或者操作):

+ processPurchaseOrder (customerInfor : Customer, purchaseOrder : PurchaseOrder) : Invoice

這一服務將由 OrderProcessor 服務提供者提供。OrderProcessor 是一個合成要素,它通過將其他服務提供者(根據需求契約設計的)連接在一起來提供一個服務。也就是說被提供的服務方法的某些方面被設計用來以某種方式使用其他服務提供者。這一合成要素通過它的購買服務端口提供 Purchasing 接口。所有的消費者接口都是通過這個端口的,從而將消費者客戶端從同合成要素同其他服務消費者或者提供者的相互作用中分割出來。這樣做限制了模型中的耦合性,隨著市場和服務消費者和提供者的變化能夠更容易的做出改變。


圖 4. Purchasing 服務規(guī)范
Purchasing 服務規(guī)范

OrderProcessor 合成要素的組織展現在圖5中所示的 Project Explorer 視圖中。


圖 5. 定購管理業(yè)務功能區(qū)域(包)
定購管理業(yè)務功能區(qū)域(包)

OrderProcessor 服務提供者包含在 org::ordermanagement 包中,它用于組織同定購管理相關的服務。定購管理包也包含相關的服務接口、服務消費者和服務提供者。

圖6中顯示的 OrderProcessor 圖表提供了 OrderProcessor 服務者及其提供的和要求的服務的一個外部視圖。(要求的服務有時被稱作請求,以便同功能需要相區(qū)分。)外部的或者叫做“黑盒”視圖是呈現給服務提供者的消費者查看的。稍后將顯示的合成要素的內部結構提供了一個支持合成要素的執(zhí)行設計結構的一個內部的或者叫做“白盒”的視圖。


圖 6. OrderProcessor 服務提供者
OrderProcessor 服務提供者

外部視圖不是一個從執(zhí)行中分離出來的規(guī)范;它僅僅是合成要素某些方面的視圖。如果架構師或者開發(fā)人員希望完全的將服務提供者的規(guī)范從它的可能執(zhí)行中分離出來,就將使用到規(guī)范合成要素。規(guī)范合成要素定義了一個服務消費者和服務提供者之間的契約,它從特定的提供者執(zhí)行中減弱了它們。規(guī)范合成要素能夠被許多具體的合成要素識別出來,這些要素以一種識別契約的方式提供服務,并且提供服務的可接受的質量。請參見“SOA 建模: 第二部分 服務規(guī)范”獲得更多細節(jié)。

OrderProcessor 服務提供者要素十分簡單和穩(wěn)定,在這個例子中,架構師和開發(fā)人員決定不使用服務規(guī)范。結果是,使用 OrderProcessor 合成要素的任何服務消費者都將同這個特定的執(zhí)行相聯系。這是不是一個充分的設計取決于有多少服務將被使用,以及隨著時間的推移它們將發(fā)生多大程度的改變。只有解決方案架構師能夠決定一個特定的系統(tǒng)能夠容忍什么程度的耦合性。

OrderProcessor 合成要素也擁有反映有其他服務提供者(貨品計價、時間表、運送)提供的需要請求的服務端口。這些服務提供者提供了 OrderProcessor 合成要素用來執(zhí)行其被提供的服務操作的那些服務。

每一個服務交互作用點都涉及到一個簡單協議,該協議影響被提供的和被要求的接口。例如,貨品計價交互作用點要求 Invoicing 接口啟動價格計算器,并且發(fā)送運送價格。然而,它可能會花費一些時間來計算運送價格,所以 OrderProcessor 通過其貨品計價端口來提供 InvoiceProcessing 接口,從而使得貨品計價服務提供者能夠在其準備好時發(fā)送一張發(fā)貨單。

潛在的耦合性問題

請注意在這個例子中有一個潛在的設計問題,它可能導致意想不到耦合性。定購處理服務提供者如何同在同一個業(yè)務過程(活動)中被捕獲的貨品計價進行相互作用的規(guī)則,就像同生產時間表和運送服務提供者相互作用的規(guī)則一樣。這使得在沒有復制交互作用協議的情況下,復用貨品計價、時間表和運送服務很困難。

這種耦合性作用經常是由業(yè)務過程服務操作的直接執(zhí)行造成的。業(yè)務過程模型關注一個活動完成一個特定的業(yè)務目標所必須的那些步驟,例如有效的定購處理。它們并不需要關注如何復制那些步驟來增加內聚性,減少耦合性,使復用變得便捷、最小化分布式通訊、處理網絡安全性、管理持久數據的完整性,等等。這些都是 IT 解決方案關注的問題,必須使用軟件架構和實用的并且經過證明的設計模式來處理。

使用服務契約,提供了一種形式上捕獲業(yè)務需求的方法,同時允許復制架構的服務提供者,同時滿足業(yè)務需求并且處理 IT 解決方案的關注。架構的解決方案和業(yè)務需求之間的鏈接使通過契約實現的,它將服務提供者的各部分同它們在服務契約中所扮演的角色綁定在一起。在這個例子中,我們不再對這些設計問題作進一步的處理,但是我們會顯示如何將服務解決方案鏈接到它所完成的業(yè)務需求上面。

Order Processor 執(zhí)行設計模型

我們現在完成了服務模型的架構,并且在服務提供者的外部視圖中捕獲到它。下一步就是為 OrderProcessor 合成要素所提供的 processPurchaseOrder 服務操作提供一種方法。這種方法必須遵循任何一個已經完成的服務契約或者已經實現的服務規(guī)范,也要遵循那些操作已經被定義的服務規(guī)范。

內部結構

OrderProcessor 服務提供者通過它的購買服務端口提供了一個簡單的服務規(guī)范 Purchasing。這個服務規(guī)范指定了一個簡單的操作 processPurchaseOrder。服務提供者必須為它所提供的全部服務操作提供一些方法。在這個例子中,我們使用 Activity 作為 processPurchaseOrder 服務操作的方法。有關的細節(jié)被顯示在提供服務的 OrderProcessor 合成要素的內部結構中。OrderProcessor 內部結構在圖表、接口、類和活動中被捕獲,如圖7中的 Project Explorer 視圖和圖8中的復合結構圖表所示。


圖 7. OrderProcessor 服務提供者的組織
OrderProcessor 服務提供者的組織

Project Explorer 視圖顯示了 OrderProcessor 提供者各個部分的列表,以及每一個被提供的操作的方法(行為)。在這個例子中所使用的約定是,使用一個和合成要素名稱一致的類圖表,并且在包含該合成要素的包中,顯示它的外部視圖。這就是圖6和圖7中所顯示的圖表。同合成要素具有同樣名稱并且被包含在合成要素中的復合結構圖表,提供了服務提供者結構的內部視圖。這個圖表直接位于圖7中的 OrderProcessor 服務提供者的下面。這些約定能夠更好的協調服務參與者的外部和內部視圖,并且如同合成要素一樣仔細研究圖表。

OrderProcessor 復合結構圖表如圖8所示,提供了一個服務提供者的內部結構的總體視圖。再一次顯示了合成要素的合成靜態(tài)結構的各個部分(端口和屬性)。


圖 8: OrderProcessor 服務提供者的內部結構
OrderProcessor 服務提供者的內部結構

OrderProcessor 合成要素的內部視圖很簡單。它由用于被提供的和被要求的接口的服務端口、加之許多其他保持服務提供者狀態(tài)的屬性共同合成。屬性 ID 被用來識別服務提供者的實例。這個屬性將被用來動態(tài)的關聯消費者和提供者的交互作用。屬性 scheduleshippingInfo 是在 processPurchaseOrder 服務操作的執(zhí)行中被使用的信息。

被提供的服務操作的方法

由服務提供者所提供的每一項服務操作必須通過以下兩種方式之一被實現:

  • Behavior (Activity、Interaction、StateMachine 或者 OpaqueBehavior),它是操作的方法;
  • 屬于合成要素的一個 Activity 中的 AcceptEventAction (異步調用)或者 AcceptCallAction (同步需求或者回復調用)。
這允許一個單一的 Activity 擁有多于一個的并發(fā)進入點,并且它符合 Business Process Execution Language (BPEL) 中的多重接收活動。這些 AcceptEventActions 通常被用來處理回叫信號,從其他異步的 CallOperationActions 中返回信息。

 

OrderProcessor 合成要素包含兩種服務實現風格的例子。processPurchaseOrder 操作擁有一個同樣名字的方法活動。這一活動,如圖9所示,是提供服務操作的服務提供者所擁有的一種行為。


圖 9: processPurchaseOrder 服務操作實現
processPurchaseOrder 服務操作實現

這個圖表同用于相同行為的 WebSphere Business Modeler 圖表非常符合。InvoiceProcessing 和 ScheduleProcessing 服務操作通過過程中的 processInvoice 和 processSchedule 接收事件行動被實現。請注意接口中的相應操作被指示為觸發(fā)器操作,它指出響應 AcceptCallActions 的能力(類似于接收和 AcceptEventActions,此處觸發(fā)器是一個 SignalEvent)。關鍵字觸發(fā)器并不是 UML 2 的一部分,它只是用來強調這些操作是如何實現的。

注釋:
除非 processPurchaseOrder 活動正在運行,并且控制流程已經到達兩個接收呼叫行動,否則這些操作將不會被接收。這指示出一個操作的執(zhí)行能夠決定其他操作何時將被響應。

實現服務契約

OrderProcessor 合成要素至此已經完成。但是還有兩件事沒有做:

  1. 首先,我們需要將 OrderProcessor 服務提供者同對其需求進行建模的業(yè)務過程相結合。
  2. 其次,我們需要創(chuàng)建一個子系統(tǒng),將能夠提供 OrderProcessor 需求接口的服務提供者和適當的服務端口連接起來。
這將導致一個能夠運行的可配置的子系統(tǒng)。這一小節(jié)將處理鏈接 SOA 解決方案和業(yè)務需求的問題。下一小節(jié)將介紹可配置的子系統(tǒng)。

 

術語

IBM? Software Services Profile 將服務協作描述為“一組服務根據某些過程規(guī)范以一種經過協議的方式共同行動”。這從本質上說是一個契約,它指定了一組服務如何被連接和設計,以達到某些目標,例如另一個服務應該如何被執(zhí)行或者某些業(yè)務目標將如何被實現。服務協作還能夠用來形式上描述需要滿足的需求。WebSphere Business Modeler 業(yè)務過程模型和 Rational Software Architect UML 建模之間的綜合,被設計為開發(fā)協作,就像描述需求的角色中心方法一樣。當它在 Rational Software Architect 中被打開的時候,它將 WebSphere Business Modeler 業(yè)務過程視作一個協作。

術語服務協作、服務需求契約業(yè)務服務需求契約都表示相似的意義,并且都使用協作來描述一組共同使用的服務的需求。這些不同的術語只不過是關注上下文環(huán)境中協作的特定使用。

本小節(jié)中的操作不會對 OrderProcessor 合成要素如何轉變?yōu)橐粋€ SOA 執(zhí)行產生任何改變。將合成要素鏈接到服務契約,只是描述合成要素如何完成那些契約所指定的需求。這并不影響服務提供者的執(zhí)行或者它將如何被轉變?yōu)橐粋€ SOA 解決方案。然而,聯接較之依賴要復雜得多。它特定的顯示服務提供者的各個部分在服務需求契約中扮演什么角色,以及合成元素完成業(yè)務的約束。這提供了更加豐富的可追溯性,對有細密紋理的變化管理的支持,以及使用模型驗證解決方案確實滿足它們的需求的能力。

圖10使用一個服務契約顯示了 OrderProcessor 服務提供者的需求,該服務契約提供了一張由業(yè)務分析師創(chuàng)建的業(yè)務過程的角色中心視圖。一個協作使用被添加到 OrderProcessor 服務提供者中,指出它所完成的服務契約。


圖 10: 實現服務契約
實現服務契約

圖10中被稱作契約的的協作使用,是圖11中所顯示的 Purchase Order Process 服務協作的一個實例。這指定了 OrderProcessor 服務提供者完成 Purchase Order Process 業(yè)務需求。角色綁定指示出服務提供者的哪一個部分在服務契約中扮演哪一個角色。例如,貨品計價端口扮演貨品計價角色,購買端口扮演 orderProcessor 角色。

這些角色綁定和下一小節(jié)中所描述的服務信道連接器并不相關。服務信道連接器被用來連接子系統(tǒng)中的消費者請求和提供者服務。角色綁定指定了該部分在服務契約中扮演什么角色。角色綁定既可以是嚴格的也可以使松散的。嚴格的契約完成意味著各個部分必須同它們所綁定到的角色類型一致。松散的契約完成意味著各個部分將會根據架構師的要求扮演那些角色,但是模型驗證并不驗證角色和部分功能。也就是說,或許因為業(yè)務服務契約不完全,或者只有業(yè)務需求的概略信息。


圖 11: Service Requirements 契約
Service Requirements 契約

顯示 SOA 解決方案如何完成業(yè)務需求要花費額外的工作來指定契約和角色綁定,但是它提供了一個管理變化的有利條件。模型查詢可能被用來決定哪一個服務提供者完成什么業(yè)務需求。需求中的任何改變將可能導致服務協作中的其中一個角色的變化。建模器于是能夠直接定位到扮演那些角色的部分,決定代表那些可能需要改變的角色的服務規(guī)范如何處理需求中的變化。模型驗證也能夠被用來決定某些角色是否被改變,以及在 SOA 解決方案中扮演該角色的各個部分不再有能力執(zhí)行角色的所有責任。這較之用例實現的不具備支持語義或者松散語義的老套依賴要強大得多。正是這種類型的形式,可驗證的 SOA 解決方案和業(yè)務需求之間的連接器(確保解決方案是業(yè)務相關的,滿足需求,并且是敏捷的解決方案),才能夠便于適應改變。

組裝 OrderProcessing 子系統(tǒng)

在我們的 SOA 解決方案中,最后要做的就是創(chuàng)建一個 OrderProcessing 子系統(tǒng),它使用我們一直執(zhí)行的服務提供者將各部分裝配到一個可配置的解決方案之中。

這個子系統(tǒng)如圖12所示,它反映了一個將 OrderProcessor 服務提供者同其他提供其需求服務的服務提供者連接起來的可配置的合成要素。這個子系統(tǒng)是提供所有配置和運行 OrderProcessor 服務的必要信息的合成要素的一個集合。


圖 12: 將各部分組裝到一個可配置的子系統(tǒng)之中
將各部分組裝到一個可配置的子系統(tǒng)之中

OrderProcessing 子系統(tǒng)包括 OrderProcessor、Invoicer、Productions 和 Shipper 服務提供者合成要素的實例。銷售者合成要素的貨品計價服務同 Invoicer 合成要素的貨品計價服務相連接。這是一個有效的連接,因為 OrderProcessor 合成要素的貨品計價服務的服務規(guī)范,正是 Invoicer 提供者的貨品計價服務的變形。OrderProcessor 合成要素要求 Invoicing 接口,它是由 Invoicer 服務提供者所提供的。它還為 Invoicer 提供了 InvoiceProcessing 接口,接收更新的貨品計價。

連接服務(服務規(guī)范的實例)意味著參與者同意根據服務規(guī)范相互作用連接器。也就是說,它們同意遵守被要求的協議。服務規(guī)范定義了協議中被連接的參與者所扮演的角色。orderProcessor 消費者的貨品計價端口和貨品計價提供者的貨品計價端口之間的服務信道連接器擁有一個契約(行為),這個行為是 InvoicingService 服務規(guī)范的 InvoicingService 行為。連接器的名稱根據約定被設置為其契約的名稱。任何經過這個連接器的交互作用都被要求遵守契約或者協議。這些連接器將服務架構中的使用依賴形式化了。

請注意,生產者和銷售者部分之間的連接器沒有契約。這是因為在 Scheduling 服務接口中沒有協議,所以該連接器不需要契約。

其他消費者和提供者以相似的方式被連接起來。連接的服務能夠提供不同的綁定風格。服務相互作用點之間的服務信道能夠指定實際使用的綁定風格。

OrderProcessing 子系統(tǒng)現在已經完成,并且做好被配置的準備。它已經指定了服務提供者完全執(zhí)行 processPurchaseOrder 服務所必須的所有被需要的實例。在它被配置以后,其他服務消費者能夠綁定到銷售者 OrderProcessor 合成要素的購買服務,并且調用該服務操作。

總結和下一步工作的展望

至此,我們已經完成了服務、消費者和提供者達到業(yè)務目標所必須的識別、規(guī)范和實現。結果得到一個和技術無關的但是完全的架構服務解決方案的設計模型。

要實際運行這一解決方案,我們需要創(chuàng)建一個同服務模型中被捕獲的架構設計決定相一致的平臺執(zhí)行。我們能夠將該模型作為向導,通過手工來創(chuàng)建這個解決方案。但是這樣做非常冗雜、易出錯、費時間、并且需要一個高水平的開發(fā)人員確保架構決定能夠正確的被執(zhí)行。當然可以通過手工來創(chuàng)建解決方案,并且將該模型作為向導也是非常有幫助的。但是,一個完全的、正式的、經過驗證的模型才能使我們有機會進行模型驅動的開發(fā)(MDD),從模型中創(chuàng)建一個解決方案的骨干,然后在特定平臺編程環(huán)境中完成細節(jié)的編碼。這正是下一篇,也就是本系列最后一篇文章:“SOA 建模: 第五部分 服務執(zhí)行”中的內容。在那篇文章中,我們使用 Rational Software Architect UML-to-SOA 轉換特性,創(chuàng)建一個能夠直接在 WebSphere Integration Developer 中執(zhí)行、測試和配置的完整的 Web 服務解決方案。



參考資料

學習

獲得產品和技術
  • 下載面向 SOMA 方法的 Rational Unified Process 插件程序:IBM RUP for Service-Oriented Modeling and Architecture。您必須具備 IBM Rational Method Composer 來安裝該插件程序。

  • 下載 RUP plug-in for SOA,使用 IBM Software Services Profile 對面向服務的 Rational Unified Process 插件程序進行建模。

  • IBM SOA Sandbox IBM SOA Sandbox 提供了完全版本軟件試驗和 “在線試用” 主機環(huán)境(在此您能夠探索指南并且獲得架構的指導)的一種混合。

  • 下載試用版本:IBM Rational Software Architect V7

  • 下載 IBM 產品評估版本,并且從 DB2?,Lotus?,Rational?,Tivoli? 和 WebSphere? 中獲得應用程序開發(fā)工具和中間件產品。


討論


關于作者

Jim Amsden

Jim Amsden 是一名 IBM 的高級技術人員,在應用程序設計和開發(fā)以及軟件開發(fā)行業(yè)工具方面有二十多年的經驗。他持有波士頓大學的計算機科學碩士學位。他的興趣點包括基于契約的開發(fā),代理編程,業(yè)務驅動開發(fā),J2EE UML,以及面向服務架構方面。他也是 "Enterprise Java Programming with IBM WebSphere" 一書的合著者。他目前關注于如何集成工具以更好地支持敏捷開發(fā)過程。

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多