從產品展示頁面談談Hybris的特有概念和設計結構
今天這篇文章來自我的同事,SAP成都研究院Hybris開發團隊的開發人員Zhang Jonathan(張健)。需要特別介紹的是,張健和成都研究院的其他開發同事不同,張健畢業於電子科技大學,讀的專業是英語,也就是說Jonathan是文科背景。但是張健畢業後的第一份居然選擇了程式設計工作,而且是在IBM大型機上的程式設計工作。沒錯,就是用下面這個龐然大物寫程式碼, 厲害吧!
然後,Jonathan在他大四上學期時,參加了IBM在電子科技大學計算機學院開展的大型機培訓,從此開始了他的大型機程式設計之路。用的程式語言是COBOL。好古老的程式語言啊!
一個英語專業的畢業生從事IBM大型機程式設計工作,這本身就很傳奇了。然而傳奇還沒有結束,2016年底,Jonathan選擇了跨程式語言跨行業,從他已經積累了豐富開發經驗的COBOL語言大型機開發領域裡,轉投Java開發。他申請了SAP成都研究院Hybris開發工程師的職位,這之前他只是業餘自學過Java,有過不到半年的Web專案經驗。
(如果是一般的軟體公司,對於這種profile和崗位需求不太符合的簡歷,可能直接就拒掉了。但是在Jonathan應聘之前,SAP成都研究院有過成功的案例。我們之前招過一位同樣是英語專業背景的應聘者。該應聘者畢業後10年期間一直從事英語專業的工作, 只是業餘時間喜歡寫程式碼。他應聘的是SAP Fiori開發工程師。成功通過面試後,他利用在SAP成都研究院工作的18個月時間,成為了一位前端大神。他叫Wu Ji吳脊)
時任SAP成都Hybris開發團隊專案經理的Derry和我一起對Jonathan進行了面試,Derry給Jonathan用優盤拷貝了一份Hybris開發環境,替他申請了一個訪問Hybris幫助文件的賬號,然後佈置了三道題目。這三道題目的內容是在這個Hybris開發環境上,給當前版本的Hybris實現一些新的功能。
Jonathan完成得非常迅速,每天通過郵件向Derry和我彙報完成進度,同時提出一些他在完成題目過程中的思考和疑問。最後只花了一週時間非常完美地完成了這三道題。我覺得考慮到他英語專業的背景和過去大型機的開發經歷,這一切簡直不可思議。
現在Jonathan在SAP成都Hybris開發團隊工作了1年多的時間,已經成長為團隊裡開發的中堅力量,贏得了團隊裡所有同事們的信任。
下文是Zhang Jonathan(張健)的原創文章。
本文介紹的Hybris全稱是Hybris ECP(Enterprise Commerce Platform), 為簡單起見,下面一律簡稱為Hybris。
Hybris是SAP旗下的電商平臺產品,在國外電商產品評測中都位居前列,是兼顧擴充套件性和易用性的綜合性平臺。下圖為gartner的2017電商產品評測報告。
注1: 上圖報告來自網站
這篇文章將結合hybris的產品展示頁面,簡單介紹一下hybris的主要概念和工程結構。
首先介紹下一些hybris特有的概念。
1. accelerator
在hybris裡,accelerator是指由一些hybris功能模組構成的,能完成b2b和b2c等電商場景的hybris例項。一般譯為加速器,用於模擬和演示用途,也可以根據客戶需求做一些簡單的定製開發直接用於生產環境。
2. recipe
recipe是用來安裝hybris的一些指令碼,具體存在於hybris的installer資料夾下的recipe子資料夾。可以用來安裝加速器,SAP整合版本乃至docker版本的hybris例項,每個recipe擁有以自己名字命名的資料夾,裡面具有一個build.gradle檔案, 其內容是所有安裝此recipe需要的指令碼。
3. extension
從業務來講,extension是服務於某個hybris業務的功能模組。從工程來講,解壓hybris後,bin資料夾的每個子資料夾內都包含一個工程資料夾,每個工程資料夾都是一個extension. recipe安裝的元件就是若干extension的組合。
4. template
hybris的設計具有很好的產品可擴充套件性,這表現為Hybris提供了很多模板工程(template extension)供客戶參考,擴充套件,或直接使用。本文介紹的產品頁面的View層就存在於yacceleratorstorefront這個模板內。
Hybris的層級結構劃分
我們再來介紹一下hybris的總體結構劃分。
Hybris和很多主流Web應用一樣,使用Spring Framework進行開發。以常見的使用Spring MVC的工程為例,一般可簡單分為前端頁面(View層),Spring MVC Controller和Spring注入的Service(Controller層),整合ORM框架的DAO(Model層)。
Hybris大致劃分為三層,和經典MVC不同在於: Hybris前端頁面和Spring MVC Controller統一為View層,Service和DAO統一為Service層,Facade(即DTO資料傳輸物件層)在中間單獨為一層。這三層都分別存在於一個extension內,繼而構成hybris工程的整體。
注2: 上圖的DTO, Converter和Populator的概念將在後續系列文章詳細介紹,這裡只需簡單理解成它們的作用就是把業務資料從資料庫裡讀取出來並且進行格式轉換便於提供給Controller用於最終將資料展現在UI上。DAO和DTO都不是Hybris特有的概念,而是軟體系統設計中的通用概念,其定義如下:
本次演示安裝的是hybris 6.5的release版本,安裝包是大小為2GB左右的zip檔案。以windows為例,解壓後,簡單用下面幾個命令就可從installer資料夾啟動一個hybris的例項。其中的initialize步驟是資料初始化的過程,時間較長請耐心等待,我們使用的b2c_china這一recipe就是SAP成都研究院的Hybris開發團隊開發的中國定製版加速器。
cd $HYBRIS_HOME_DIR/installer install.bat -r b2c_china setup install.bat -r b2c_china initialize install.bat -r b2c_china start
在hybris啟動完畢後,用如下連結開啟首頁後,任意點選一個產品即可進入產品詳情頁面。
因為一個hybris例項可以支援多個電商網站共享一套程式碼,類似SAP Hybris Cloud for Customer裡的multi-tenant的概念, 所以訪問某一網站需要加上site這個引數。
如下圖:
本文接下來將介紹從使用者點選產品連結,到看到該產品的詳情頁面這一過程,Hybris應用背後到底發生了哪些事情。
產品的連結是以”/p/+產品程式碼”結尾的一串很長的字元,”/p/”之前的部分是用產品詳細類別和產品名稱拼成的,根路徑是yacceleratorstorefront。
前面也提到過yacceleratorstorefront是hybris主要的view層template extension,它位於bin/ext-template目錄下。在它的web/src目錄下有spring mvc controller的程式碼; web/webroot目錄下則包含了所有的前端頁面程式碼(使用JSP+Jquery)。
在上述web/src目錄中找到產品頁面展示的ProductPageController裡的方法productDetail(productCode),其中獲取產品明細資料通過呼叫facade層的productFacade.getProductForCodeAndOptions(productCode, extraOptions) 方法,可以繼續檢視此方法的實現,看它如何返回產品的DTO物件ProductData。
在facade的具體實現DefaultProductFacade裡,可以看到ProductData是由ProductConverter的convert方法基於ProductModel生成的。那麼什麼是Converter呢?為什麼一定要呼叫它來生成DTO物件呢?
這裡我們可以先找到DefaultProductFacade的位置,它位於bin/ext-commerce這個資料夾下的commercefacades。這個extension正如它的命名,實際上還提供了很多如訂單,產品目錄等等的commerce相關的DTO物件。觀察它的結構,可以找到resource資料夾下有兩個xml檔案,commercefacades-beans.xml和commercefacades-spring.xml。前者是定義DTO物件的地方,後者當然是提供spring配置的。
在Hybris裡,無論DTO物件(以Data結尾的Java類)還是DAO物件(以Model結尾的Java類), 都不是通過直接手動編寫Java程式碼來建立的,而是通過在xml檔案裡定義物件屬性, 然後經過編譯,以POJO(Plain old Java object)的形式生成在platform這個extension裡。 通過這種基於配置檔案生成Java類的方式,實現了物件定義和程式碼的隔離。這樣即使以後需要給物件增減屬性, 再也不用去逐一新增修改屬性對應的get和set方法,只需要改變xml裡對應的定義,重新編譯即可。
注3: POJO也不是SAP Hybris的一個專屬概念,而是軟體設計裡的一個通用概念。Wiki定義如下:
下一篇我們將詳細介紹Hybris的Facade層和Service層, 包括DTO, DAO, Conveter, Populator這些模組的作用。
要獲取更多Jerry的原創技術文章,請關注公眾號”汪子熙”或者掃描下面二維碼: