|
在2005年的時(shí)候,我曾經(jīng)基于.NET 2003開發(fā)了一個(gè)小的組件,這個(gè)組件的目的是為了解決模塊化開發(fā)和模塊復(fù)用的問題。我將該組件命名為Common Form Framework,它的目的是允許每一個(gè)開發(fā)人員獨(dú)立的開發(fā)自己的模塊且可以直接專注于業(yè)務(wù)模塊,然后通過配置可以快速將所有開發(fā)人員開發(fā)的業(yè)務(wù)邏輯窗體集成到這個(gè)組件中。
該組件的思路如下圖所示。該組件提供了一個(gè)如“2”標(biāo)識(shí)的空的窗體,每一個(gè)開發(fā)人員通過編寫一個(gè)如“1”的XML配置文件即可將一個(gè)模塊的功能附加到空窗體,最終組合成一個(gè)如“3”所示的軟件產(chǎn)品。
這個(gè)組件成功的應(yīng)用在一個(gè)由9個(gè)人合作開發(fā),歷時(shí)1年的應(yīng)用系統(tǒng)開發(fā)中。它的想法和Microsoft Composite Application Block有一些類似,不過沒有CAB那么強(qiáng)大了。
在參考了CAB和經(jīng)歷更多應(yīng)用系統(tǒng)之后,我發(fā)現(xiàn)該組件有不少缺點(diǎn),比如:模塊化定義不夠標(biāo)準(zhǔn)、界面元素?zé)o法擴(kuò)展、模塊交互非常復(fù)雜、功能復(fù)用低、不能應(yīng)用于Web或者其它應(yīng)用環(huán)境等。為此,我參考了CAB和SCSF的一些功能,并在2007設(shè)計(jì)了一個(gè)Commom UI Platform規(guī)范,旨在設(shè)計(jì)一個(gè)更為強(qiáng)大簡單的模塊化快速開發(fā)平臺(tái)。
不過在2008年的時(shí)候,我有了更多的想法,提出了一個(gè)UIShell產(chǎn)品構(gòu)思。UIShell是英文User Interface Shell的縮寫,中文譯為“用戶界面外殼”。它是由一個(gè)軟件模板框架。它由框架層、服務(wù)層、Shell層和系統(tǒng)模塊層組成,提供了基于UIShell的軟件設(shè)計(jì)和開發(fā)規(guī)范。 Shell中文譯為“外殼”,它是應(yīng)用系統(tǒng)的主界面,由可擴(kuò)展的界面元素(如菜單、工具欄)和可替換的界面(如顯示區(qū))元素組成,如下圖所示。
這個(gè)產(chǎn)品面向的用戶有2種:(1)開發(fā)人員——該產(chǎn)品能夠?yàn)殚_發(fā)人員提供一個(gè)模塊化設(shè)計(jì)規(guī)范、通用的界面框架和通用的服務(wù),從而使得開發(fā)人員可以直接設(shè)計(jì)業(yè)務(wù)模塊,不需要關(guān)心軟件的界面、用戶體驗(yàn)等;(2)最終用戶——最終用戶不需要去購買任何軟件,可以通過基于該平臺(tái)的軟件超市中下載到所需的界面框架和應(yīng)用模塊,然后自己組裝成最終的軟件。
在我現(xiàn)在看來,當(dāng)時(shí)的想法確實(shí)有點(diǎn)瘋狂,因?yàn)槲蚁氲奶唵翁h(yuǎn)大了(不過,有時(shí)候還真需要瘋狂才能干點(diǎn)什么,:)),不過我那會(huì)一點(diǎn)都沒有意識(shí)到這點(diǎn)。我當(dāng)時(shí)組了一個(gè)UIShellDev Team。我很驕傲的告訴團(tuán)隊(duì),“一旦我們實(shí)現(xiàn)了UIShell,我們或許能夠?yàn)檐浖袠I(yè)開辟一個(gè)新的方向,為其貢獻(xiàn)點(diǎn)什么”。
于是我們便開始了UIShell產(chǎn)品之路,我們瘋狂的學(xué)習(xí)了Enterprise Library、SCSF、SharpDevelop、Egeye Addin、MAF、MEF等,分析了SCSF的源代碼、SD源代碼,學(xué)習(xí)了Framework Design Guideline,關(guān)注每一個(gè)新出現(xiàn)的產(chǎn)品并分析競爭優(yōu)勢與劣勢(如Google App Engine、Sina App Engine、MEF等,我們不能開發(fā)一個(gè)對(duì)開發(fā)人員來講沒有用且過時(shí)的產(chǎn)品,因此需要時(shí)刻保持警惕),制定了產(chǎn)品開發(fā)規(guī)范——“用戶場景設(shè)計(jì)規(guī)范、需求規(guī)范、設(shè)計(jì)規(guī)范、質(zhì)量保證體系等”…… 這個(gè)產(chǎn)品設(shè)計(jì)目標(biāo)以“易用性”為首要目標(biāo),這意味著我們做任何功能都應(yīng)該先想到用戶,并模擬用戶的行為習(xí)慣來不斷的優(yōu)化產(chǎn)品的設(shè)計(jì)。然而這條路并沒有像我預(yù)想的那么容易,我原來以為這個(gè)產(chǎn)品早該在2009年底就發(fā)布了。設(shè)計(jì)的過程中,問題一個(gè)接一個(gè),且由于我們團(tuán)隊(duì)是兼職的,進(jìn)度比我預(yù)想的慢了許多。更為重要的是,當(dāng)時(shí)想法是基于SCSF來做的,SCSF太過于復(fù)雜,并不能夠滿足我們的需求。在一個(gè)偶然的機(jī)會(huì),我接觸了OSGi規(guī)范,并利用業(yè)余時(shí)間將OSGi規(guī)范翻譯了??戳?/span>OSGi后,我眼前一亮,我意識(shí)到了這就是我想要的。然而OSGi是基于Java的規(guī)范,由于.NET平臺(tái)和Java平臺(tái)的差異,我們需要設(shè)計(jì)一個(gè)符合.NET平臺(tái)的規(guī)范。于是,我們便動(dòng)手自己設(shè)計(jì)了OSGi.NET規(guī)范,在設(shè)計(jì)這個(gè)規(guī)范時(shí),我們借用了OSGi規(guī)范但調(diào)整了它的目標(biāo),即OSGi.NET的定位是一個(gè)滿足.NET不同應(yīng)用環(huán)境的通用模塊化運(yùn)行時(shí),它實(shí)現(xiàn)了OSGi的模塊化與插件化、面向服務(wù)、模塊擴(kuò)展和安全性的功能。
OSGi.NET規(guī)范及接口設(shè)計(jì)在2008年底設(shè)計(jì)完成,我記得當(dāng)時(shí)完成設(shè)計(jì)的時(shí)候,我正在美國的Dublin,通過Email把設(shè)計(jì)的圖紙和規(guī)范發(fā)送給UIShellDev Team。這是該規(guī)范的初稿。在接下來的日子里,我們不斷的對(duì)設(shè)計(jì)進(jìn)行重構(gòu),最終在2009年8月份實(shí)現(xiàn)了內(nèi)核原型,在2009年10月份完成了OSGi.NET設(shè)計(jì)最終稿。當(dāng)然,在重構(gòu)的過程中,團(tuán)隊(duì)其他成員已經(jīng)開始動(dòng)手設(shè)計(jì)了。在這里我們設(shè)計(jì)了一個(gè)能夠通用于各種.NET運(yùn)行環(huán)境的模塊化運(yùn)行時(shí),它實(shí)現(xiàn)了UIShell產(chǎn)品所有功能,并且易用性依然保持。我們自行設(shè)計(jì)了模塊化規(guī)范、模塊運(yùn)行時(shí)類加載規(guī)范、SOA規(guī)范和擴(kuò)展規(guī)范、開發(fā)與調(diào)試規(guī)范。不過,中間有一個(gè)決策比較困難,因?yàn)?/span>ASP.NET不同于WinForm、WPF和Console,它必須宿主在Web Server。那么,我們的爭論就在于——是IIS宿主模塊運(yùn)行時(shí)還是模塊運(yùn)行時(shí)宿主IIS呢?如果模塊運(yùn)行時(shí)宿主IIS,那么它就有完全的控制權(quán),不夠運(yùn)行于IIS的模塊與模塊運(yùn)行時(shí)的其它模塊間的通訊就麻煩了,因?yàn)檫@是跨進(jìn)程通訊。如果IIS宿主模塊運(yùn)行時(shí),那么模塊運(yùn)行時(shí)就比較被動(dòng)了。最終討論的結(jié)果是采用第二種方案,因?yàn)檫@種方案性能高、簡單。在完成最終稿設(shè)計(jì)時(shí),產(chǎn)品設(shè)計(jì)的所有問題便解決了。我們便投入所有的精力去實(shí)現(xiàn)。
目前UIShell產(chǎn)品設(shè)計(jì)與實(shí)現(xiàn)已經(jīng)進(jìn)入尾聲,這也意味著軟件超市的基礎(chǔ)平臺(tái)已經(jīng)基本構(gòu)建完成。我們實(shí)現(xiàn)的OSGi.NET內(nèi)核已經(jīng)能夠成功的宿主在.NET各種不同環(huán)境,并且各種環(huán)境的設(shè)計(jì)思路、開發(fā)思路完全一致。軟件超市以后將會(huì)有不同環(huán)境的Shell模塊、通用服務(wù)和應(yīng)用模塊,這樣,用戶和開發(fā)人員都可以去下載和組裝軟件,并且也可以去貢獻(xiàn)自己開發(fā)的東西。
還需要提到的是,UIShell產(chǎn)品在實(shí)現(xiàn)的過程中,關(guān)于質(zhì)量保證體系的構(gòu)建。事實(shí)上,產(chǎn)品設(shè)計(jì)的初始階段,我是很希望所有的東西都能夠非常的完善,包括質(zhì)量保證體系,我當(dāng)時(shí)是一個(gè)完美主義者。不過,我們并沒有足夠的資源來支撐“完美”。在這一過程中,我學(xué)會(huì)了妥協(xié)、學(xué)會(huì)了“軟件中庸”,我們只能把有限的資源投入到最需要的地方,況且每一個(gè)階段的目標(biāo)還不同。當(dāng)然了,我們現(xiàn)在已經(jīng)構(gòu)建了一個(gè)簡單且有效的質(zhì)量保證體系,它基于“Subversion/TotoiseSVN/AnkhSVN + CruiseControl.NET/NAnt + BugTracker.NET”實(shí)現(xiàn)。Subversion提供了類似ClearCase的配置管理功能,是一個(gè)開源免費(fèi)的產(chǎn)品,它提供了強(qiáng)大的Branch/Tag管理,Branch/Tag是我當(dāng)時(shí)選擇配置管理工具的首要要求,這是產(chǎn)品線管理的必備功能。CruiseControl.NET/Nant用于持續(xù)集成,在每一個(gè)代碼更新時(shí),它都會(huì)自動(dòng)Build,我們可以看到產(chǎn)品線是否健康,此外,還有一個(gè)很重要功能,我們可以隨時(shí)構(gòu)建一個(gè)新的用于測試的安裝包。BugTracker.NET也是一個(gè)開源的缺陷管理工具,我們可以隨時(shí)創(chuàng)建Bug。它在每次Bug更新時(shí),都會(huì)向團(tuán)隊(duì)發(fā)送郵件。它提供了強(qiáng)大的缺陷統(tǒng)計(jì)管理,在Bug Fixing階段,我們可以方便的安排產(chǎn)品不同階段需要Fix的所有Bug,也可以用于統(tǒng)計(jì)每一個(gè)人的工作量。當(dāng)然了,我們還根據(jù)需要對(duì)BugTracker.NET進(jìn)行了改進(jìn),主要有2個(gè):(1)當(dāng)代碼提交時(shí),Bug狀態(tài)自動(dòng)變?yōu)?/span>Check in并發(fā)送郵件;(2)加入代碼審計(jì)功能,可以方便的為每一個(gè)Bug生成代碼審計(jì)包,從而使得我們可以方便查看每一個(gè)Bug所做的更改。以下是一個(gè)BugTracker.NET Email通知示例。
目前UIShell內(nèi)核產(chǎn)品由安裝包工程、VS插件工程、Remote Console工程、OSGi.NET工程、SaaS工程、Web Extension工程、Shell工程、測試工程和Help工程構(gòu)成。只要在不同環(huán)境中采用如下方式宿主模塊運(yùn)行時(shí),這個(gè)環(huán)境便具有了OSGi.NET的所有特性。現(xiàn)在經(jīng)過測試的環(huán)境有控制臺(tái)、WinForm和ASP.NET,接下來我們在完善了文檔、Sample之后將發(fā)布第一個(gè)版本,并在下個(gè)版本中實(shí)現(xiàn)對(duì)更多環(huán)境的集成測試,完善產(chǎn)品,并構(gòu)建軟件超市網(wǎng)站。
此外,我們還將構(gòu)建一個(gè)SaaS商店,不過這是另一個(gè)產(chǎn)品了,我將會(huì)在以后介紹我們SaaS商店產(chǎn)品了。最后我要感謝UIShellDev Team的所有成員,他們?yōu)楫a(chǎn)品的構(gòu)建付出了很大的努力,提出了很多有建設(shè)意義的想法,這個(gè)產(chǎn)品是一個(gè)團(tuán)隊(duì)的結(jié)晶。在產(chǎn)品研發(fā)過程中,我們體驗(yàn)了團(tuán)隊(duì)1+1>2的力量。沒有他們的付出,UIShell產(chǎn)品是不可能實(shí)現(xiàn)的,更別提其它宏偉的想法了。每次想起與團(tuán)隊(duì)開發(fā)過程中的細(xì)節(jié),我都非常的驕傲和感動(dòng),這些人真nice!
namespace SimpleBundleShell
{
class Program
{
static void Main(string[] args)
{
// 啟動(dòng)模塊化運(yùn)行時(shí),這樣,它就會(huì)自動(dòng)的從plugins加載所有模塊
// 并啟動(dòng)它們。在這里,一個(gè)模塊=普通.NET項(xiàng)目 + Manifest.xml。
// 因此,模塊的開發(fā)和我們原來開發(fā)一個(gè).NET項(xiàng)目的方式是完全一樣
// 的,我們不需要學(xué)習(xí)新的知識(shí)。
using (BundleRuntime bundleRuntime = new BundleRuntime())
{
bundleRuntime.Start();
Console.WriteLine("Press enter to exit...");
Console.ReadLine();
}
}
}
}
NET技術(shù):瘋狂的想法——基于.NET的軟件超市平臺(tái)構(gòu)想與5年實(shí)現(xiàn)之路,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時(shí)間聯(lián)系我們修改或刪除,多謝。