本架構(gòu)主要目的是改進(jìn)軟件開發(fā)中松耦合、增加模塊的重用性,、提高開發(fā)效率,。
在常規(guī)的模塊間方法直接調(diào)用式開發(fā)中,新增的功能對原有模塊代碼的穩(wěn)定性,、重用性破壞大,不利于軟件的后期維護(hù),,且開發(fā)效率低。
另外,,在傳統(tǒng)的軟件開發(fā)方法中,,如果新增的功能的邏輯在其它模塊需要重復(fù)使用,則只能通過copy代碼或方法調(diào)用的方式來重用,,還是需要改動原代碼,。 通過本技術(shù)方案,可以將一些功能抽像為組件,,這些組件可以被動態(tài)的插入的現(xiàn)有模塊中,,不需要改動原有模塊代碼,,從而增加了重用性,提高了開發(fā)效率,。
技術(shù)解決方案
A. 相關(guān)概念抽像及定義
首先在軟件的業(yè)務(wù)模塊中抽像出核心業(yè)務(wù)邏輯(Core Service)及核心業(yè)務(wù)數(shù)據(jù)(Core Data Model),,同時抽像出核心業(yè)務(wù)邏輯相對應(yīng)的事件接口(Event Interface)。 在核心業(yè)務(wù)之外的業(yè)務(wù)被稱之為組件(Component),,組件是由一組業(yè)務(wù)插件(Plugin)組成的,,這些插件是一個或多個核心業(yè)務(wù)的事件的實(shí)現(xiàn)體,核心業(yè)務(wù)和事件的關(guān)聯(lián),,
是通過插件樁(Plugin Bundle)收集起來的,,具體的關(guān)聯(lián)關(guān)系是在一個名為Component.xml(組件描述文件)中定義的。
B. 組件的開發(fā)
當(dāng)需要在核心業(yè)務(wù)邏輯中插入新的邏輯時,,需要定義出相應(yīng)的插件,,使插件實(shí)現(xiàn)相應(yīng)的業(yè)務(wù)事件接口,在插件中實(shí)現(xiàn)具體業(yè)務(wù)邏輯代碼,,其需要的核心業(yè)務(wù)數(shù)據(jù)會通過事件接口做為參數(shù)傳遞過來,,這樣插件就可以無入侵式的操作核心業(yè)務(wù)數(shù)據(jù)了。
C. 組件的加載和啟動
首先組件有以下狀態(tài):安裝狀態(tài)和啟動狀態(tài),,分別為已安裝和未安裝,,已啟動和未啟動。 當(dāng)系統(tǒng)啟動時,,組件加載模塊查找所有的Component.xml,,并解析出插件和核心業(yè)務(wù)的關(guān)聯(lián)關(guān)系,并將這種關(guān)系通過組件視圖(Component View)記錄在內(nèi)存中,。 在加載過程中,,檢測數(shù)據(jù)中是否有此組件的記錄,如果沒有則在數(shù)據(jù)中記錄,,此時組件的狀態(tài)被標(biāo)記為未安裝,、未啟動。如果數(shù)據(jù)庫中已經(jīng)存在則檢測其狀態(tài),,如果是已啟動狀態(tài),,則將此組件啟動,并標(biāo)記為已啟動狀態(tài),。 在系統(tǒng)的控制臺中展示組件的列表,,并提供操作按鈕,可以執(zhí)行以下操作:安裝/卸載,、啟動/停用,。 綜上所述,組件被啟動可能通過兩種途徑:系統(tǒng)加載時或在控制臺中手動啟動,。組件被啟動后,,根據(jù)組件視圖中記錄的關(guān)系將插件和插件樁進(jìn)行關(guān)系綁定,,即將插件動態(tài)插入到插件樁中,即完成業(yè)務(wù)邏輯動態(tài)地,、無侵入式地插入到核心業(yè)務(wù)邏輯中,。
D. 插件調(diào)用邏輯說明
在軟件運(yùn)行中,當(dāng)核心業(yè)務(wù)邏輯被調(diào)用的同時調(diào)用事件接口,,同時向接口傳遞核心業(yè)務(wù)數(shù)據(jù),,這個過程被稱為事件激發(fā)。 當(dāng)事件激時,,插件樁里已經(jīng)收集了相應(yīng)的插件集合(事件的實(shí)現(xiàn)體),,進(jìn)而在插件樁中一個個的調(diào)用插件,傳遞核心數(shù)據(jù),,這樣插件被執(zhí)行,。
方案的效果
通過上述組件的技術(shù)方案,可以實(shí)現(xiàn)對原系統(tǒng)無侵入式的,、松耦合式的開發(fā),,開發(fā)人員無需關(guān)系核心代碼細(xì)節(jié),只要了解事件接口就可以完成對核心業(yè)務(wù)的擴(kuò)展,,開發(fā)效率高、重用性高,。 效果舉例:以電子商務(wù)系統(tǒng)為例,,在一個電商業(yè)務(wù)中創(chuàng)建訂單是核心的業(yè)務(wù)邏輯,在訂單創(chuàng)建成功后,,可能需要發(fā)送一條手機(jī)短信給顧客,, 基于此種組件方案,開發(fā)人員需要開發(fā)一款基于某個電信網(wǎng)關(guān)的短信發(fā)送組件,。開發(fā)人員不必了解訂單創(chuàng)建的具體代碼,,只需關(guān)心如何跟電信網(wǎng)關(guān)對接即可,組件機(jī)制會將訂單信息,、顧客手機(jī)號等核心數(shù)據(jù)通過訂單的創(chuàng)建事件傳遞給插件,,插件拿到上述數(shù)據(jù), 根據(jù)具體接入的電信網(wǎng)關(guān)參數(shù),,將核心數(shù)據(jù)(訂單信息,、顧客手機(jī)號)組織好文字,傳遞給電信網(wǎng)關(guān)就完成了通過此短信網(wǎng)關(guān)發(fā)送訂單短信的功能,。 一旦業(yè)務(wù)發(fā)生變更,,比如要更換其它短信網(wǎng)關(guān)發(fā)送短信,此時再根據(jù)具體的網(wǎng)關(guān)參數(shù)開發(fā)另一款短信組件,,然后停用之前的短信組件,,安裝上新的組件即可,。 可以看出,從功能開發(fā),,到后期的變更維護(hù),,訂單創(chuàng)建的核心業(yè)務(wù)代碼從未暴露給組件開發(fā)人員,他們也不需要去改動核心代碼,,保持了原有系統(tǒng)的穩(wěn)定性,,降低了新功能開發(fā)的難度,而且基于同樣規(guī)則的系統(tǒng)都可以安裝此短信組件,,直接使用,,極大的降低了開發(fā)成本。
實(shí)際應(yīng)用
我們以本架構(gòu)在javashop電商系統(tǒng)中的應(yīng)用案例說明:
一,、訂單的創(chuàng)建和短信發(fā)送
A. 訂單核心業(yè)務(wù)
1.訂單核心業(yè)務(wù)(OrderService) 負(fù)責(zé)訂單的創(chuàng)建,,這屬于電商業(yè)務(wù)的核心,通過createOrder()方法創(chuàng)建訂單,。 2.訂單插件樁(OrderPluginBundle) 在其pluginList屬性中存儲了所有響應(yīng)訂單業(yè)務(wù)事件的插件,。
3.訂單創(chuàng)建接口 訂在訂單創(chuàng)建成功后,會激發(fā)此事件,,而實(shí)際調(diào)用的是上述pluginList中的插件,。 B. 組件的組成
如上圖所示,訂單短信組件由以下內(nèi)容: 1. 訂單短信組件(OrderSmsComponent) 訂單組件類,,在組件被安裝時會調(diào)用其install方法,,完成一些安裝必要的操作。
2. 訂單短信插件 此類實(shí)現(xiàn)了訂單創(chuàng)建事件,,響應(yīng)了訂單完成事件(onOrderCreate)方法,,當(dāng)訂單創(chuàng)建完成時,會調(diào)用此方法,。
3. 組件的描述文件Component.xml 此描述文件定義了訂單插件(OrderSmsPlugin)要注入到訂單插件樁中,,即定義了插件要對應(yīng)的核心業(yè)務(wù)
C. 組件加載、啟動過程
組件的加載,、啟動過程細(xì)節(jié)如下: 當(dāng)系統(tǒng)啟動時,,組件加載模塊查找所有的,并解析出插件和核心業(yè)務(wù)的關(guān)聯(lián)關(guān)系,,并將這種關(guān)系通過組件視圖記錄在內(nèi)存中,。 在加載過程中,檢測數(shù)據(jù)中是否有此組件的記錄,,如果沒有則在數(shù)據(jù)中記錄,,此時組件的狀態(tài)被標(biāo)記為未安裝、未啟動。如果數(shù)據(jù)庫中已經(jīng)存在則檢測其狀態(tài),,如果是已啟動狀態(tài),,則將此組件啟動。 組件啟動首先將插件注入到相應(yīng)的插件樁中,,此時當(dāng)事件被激發(fā)時,,通過插件樁就可以調(diào)用到實(shí)現(xiàn)了此事件的所有插件了。組織好插件的關(guān)系后,,將此組件在數(shù)據(jù)庫中標(biāo)記為已啟動,。
D. 事件激發(fā)及插件調(diào)用
如上圖所示,描述了事件激發(fā)和插件調(diào)用的過程,,具體技術(shù)實(shí)施細(xì)節(jié)如下: 在這里循環(huán)所有的訂單創(chuàng)建事件調(diào)用之(激發(fā)事件接口),,這些事件實(shí)際是被注入進(jìn)來的、具體的插件實(shí)現(xiàn)體,,比如訂單短信插件,,此時訂單短信插件被動態(tài)調(diào)用,在此插件中完成發(fā)送短信的邏輯,。
通過上述架構(gòu)的實(shí)施,,可以達(dá)到如下效果:
現(xiàn)在短信的廠商眾多,我們分別為其實(shí)現(xiàn)“短信發(fā)送插件”,,這對于“訂單核心邏輯”代碼是不需要改動的,,
一方面提升了核心代碼的穩(wěn)定,一方面增加可對“新短信廠商”的擴(kuò)展性,。
后記
通過這種組件架構(gòu),,其實(shí)在電商架構(gòu)領(lǐng)域中還有很多模塊可以采用組件式的架構(gòu),以javashop電商系統(tǒng)中的應(yīng)用為例:
支付組件
訂單的支付為核心邏輯,,他來處理狀態(tài)改變,記錄日志等,。
通過調(diào)用支付插件來完成具體的支付操作,,傳遞的是支付金額,訂單號核心標(biāo)準(zhǔn)數(shù)據(jù),。
而支付插件可以多種實(shí)現(xiàn):支付寶,、微信、銀聯(lián)等等,。
這樣增強(qiáng)了訂單核心的穩(wěn)定,,提高了支付方式的擴(kuò)展性
物流查詢
查詢動作和展示是核心,傳遞給插件“物流公司”,,“物流單號”核心標(biāo)準(zhǔn)數(shù)據(jù)
物流查詢有多種插件實(shí)現(xiàn):kuaidi100,,showapi,菜鳥等等。
同樣增強(qiáng)了訂單核心的穩(wěn)定,,提高了物流查詢廠商的擴(kuò)展性
圖片存儲
圖片都上傳和顯示是核心,,傳遞給插件圖片流是核心標(biāo)準(zhǔn)數(shù)據(jù)
圖片的存儲有多種插件實(shí)現(xiàn):如阿里oss,七牛、又拍等等,。
同樣增強(qiáng)了系統(tǒng)核心的穩(wěn)定,,提高了圖片存儲廠商的擴(kuò)展性
其實(shí)還有很多邏輯可以采用這種思路,提高穩(wěn)定性,,提高擴(kuò)展性,,在這里就不一一列舉
這需要對自己的系統(tǒng)功能進(jìn)行分析抽象,抽象出核心邏輯,、插件接口標(biāo)準(zhǔn),、標(biāo)準(zhǔn)數(shù)據(jù)。
|