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