摘要:[Architecture] Service Plugin
動機 :
Plugin是在軟體系統內增加功能的功能。
如果在軟體系統加入Plugin功能,能提高軟體系統的重用性。
加入Plugin功能的軟體系統在開發完成之後。
如果需要額外加入功能,不用變更已完成的軟體系統就能加入新功能。
並且因為不用變更已完成的軟體系統,也就避免了修改軟體系統會產生的風險。
另外在系統裡加入Plugin功能,其實會遇到一個問題。
當有多個Plugin內容加入系統的時候,該如何去識別與取得加入的Plugin內容。
本文介紹一個『Service Plugin 模式』,
定義物件之間的職責跟互動,用來實現Plugin提供的功能,並且封裝Plugin內容識別與取得的職責。
為自己做個紀錄,也希望能幫助到有需要的開發人員。
結構 :
下圖是這個模式的示意圖,整個看起來有點複雜。
我們將圖拆解開來說明,會比較方便了解。
ServiceLIfetime相關物件
首先是ServiceLIfetime相關物件。
這組物件主要功能是,封裝Plugin內容的生命週期啟動與結束。
至於該啟動哪些Plugin內容,則是由外部設定資料來Reflection生成。
主要的參與者有:
ServiceLifetimeContext
-管理所有Plugin內容生命週期的物件。
-使用ServiceLifetimeControlRepository,取得所有提供操作的IServiceLifetimeControl實做。
-操作IServiceLifetimeControl來管理Plugin內容的生命週期。
IServiceLifetimeControl
-提供用來管理Plugin內容的生命週期的操作的介面。
-實做IServiceLifetimeControl介面的物件,用來管理Plugin內容的生命週期。
ServiceLifetimeControlRepository
-取得所有提供操作的IServiceLifetimeControl實做。
-使用外部設定資料來Reflection生成IServiceLifetimeControl實做。
透過下面的圖片說明,可以了解ServiceLIfetime相關物件之間的互動流程。
Meteorology Service相關物件
再來是Meteorology Service相關物件
這組物件是封裝Plugin內容,並且提供管理Plugin內容生命週期的功能,也實做了Plugin內容識別與取得。
這邊使用一個,模擬一個氣象資料查詢Plugin內容來做說明。
主要的參與者有:
WeatherService
-模擬的Plugin內容,提供詢問天氣的服務介面。
WeatherServiceHost
-Plugin內容的Singleton實做物件。
-存放WeatherService物件的參考,用來提供類似 Service locator的功能,實做Plugin內容的識別與取得功能。
WeatherServiceLifetimeControl
-實做IServiceLifetimeControl介面的物件。
-提供管理Plugin內容生命週期的功能。
-在建立WeatherService時,將WeatherService物件的參考存放到WeatherServiceHost。
-在釋放WeatherService時,將WeatherService物件的參考從WeatherServiceHost移除。
透過下面的圖片說明,可以了解Meteorology Service相關物件之間的互動流程。
Meteorology GUI相關物件
最後是Meteorology GUI相關物件
這組物件主要是封裝,使用Plugin內容的使用者介面。
這個使用者介面使用模式中Plugin內容識別與取得功能,取得Plugin內容來使用。
基本上使用者介面,要使用一個UI層級Plugin模式來做掛載。
這個部分超過本篇的範圍,有興趣的開發人員可以參考 : [WPF] MVVM Plugin
這邊使用一個,模擬一個氣象資料查詢Plugin內容的使用者介面來做說明。
主要的參與者有:
DisplayWeatherPage
-模擬的UI層級Plugin內容,提供顯示天氣的使用者介面。
-使用WeatherService取得天氣資料。
DisplayWeatherPageFactory
-建立DisplayWeatherPage的工廠物件。
-透過WeatherServiceHost取得WeatherService,用來建立DisplayWeatherPage。
-這個物件存在的理由,是為了讓DisplayWeatherPage移除對於WeatherServiceHost的相依。
透過下面的圖片說明,可以了解Meteorology GUI相關物件之間的互動流程。
分析整個模式結構可以發現,
屬於UI層級Plugin內容的DisplayWeatherPage,最終只相依屬於Service層級Plugin內容WeatherService。
這兩個Plugin內容不相依於,模式裡實現Plugin職責的物件。
也就是Plugin內容可以獨立於整個模式之外,這極大的提高了重用性。
實做 :
範列下載 :
範例的程式碼較多,實做說明請參照範例程式內容。
ServicePluginSample點此下載
範列實做 :
範例內容,實做一個簡易的Shell用來提供UI層級Plugin功能。
另外它也套用了『Service Plugin 模式』,讓它可以依照設定檔,加入對應的Service提供Plugin UI使用。
透過這個範例,可以清楚的了解如何實做以及執行效果。
實做內容的說明,因為大多已在結構流程圖做了說明,這邊就不再花費篇幅做介紹。
後記 :
在系統裡加入Plugin功能,其實也就是半強迫的將整個系統拆解為片段來做思考設計。
這讓開發人員在開發時,縮小了思考範圍,隱性的就能提升軟體的品質。
並且當開發一個銷售周期較長的軟體產品時,良好的Plugin功能也提供了後續增加客製化功能的空間。
大量累積一些開發上的優點,能讓開發人員準時回家吃晚餐 :D。
能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。