GitHub:https://github.com/iccb1013/Sheng.Winform.IDE
SailingEase WinForm Framework WinForm開發框架開發手冊:http://docs.shengxunwei.com/Home/Browser/sewinformfw/
直接切入正題,這是我09年到11年左右業余時間編寫的項目,最初的想法很簡單,做一個能拖拖拽拽就直接生成應用程序的工具,不用寫代碼,把能想到的業務操作全部封裝起來,通過配置的方式把這些業務操作組織起來運行。
項目的核心功能已經基本實現,但12年之后我基本停止了這方面的開發,現在翻出來在這里寫出來想和大家交流一下。
鑒於篇幅和精力的原因,請原諒我這篇博文對於技術實現的具體細節談的不是很多,只能算是一個概述。對業務的說明也不多,我想大家都是技術流,應該一看就明白。
寫這個項目的時間是五六年前,現在回過頭去看,有很多不足之處,設計上的,技術上的都有,加上當時技術力有限,不足之處還請指正,謝謝。
后續是否會寫一個系列的博文詳細的分析講解實現方法,我暫時也沒有想好,主要是沒有太多時間,我現在基本又回到了當初每天只睡四五個小時的狀態。
如果此篇博文有點兒價值,給個推薦唄 ^_^
項目使用了 .Net Framework 3.5 開發,分為兩大塊: IDE 和 運行時(解析器)
IDE中開發的項目在打包后生成 zip 格式的包,解析器通過讀取 zip 包實時解析運行,有點類似中間語言的概念,但我這里生成的 zip 包中主要以 xml 文件為主,通過 xml 文件對項目的 UI,業務,數據結構 進行描述。
到此可以看出,運行時本身並不一定是 .Net 或 WinForm 的,而是可以使用任何平台或語言實現,只要讀取 zip 文件和 xml 文件並解析即可。
事實上我自己實現的默認運行時也不是 WinForm,而是用了 Silverlight。
再簡單說說 IDE 的設計思路,幾個主要的設計目標如下:
1.像 Visual Studio 一樣
有可視化的環境,拖拖拽拽界面就出來了。
2.模塊化設計
功能模塊全部獨立,解耦,以插件的形式存在於主程序(宿主)中。
2.不要寫代碼,業務通過界面,向導進行配置
拖一個按鈕上去,想要單擊時做一件事情,就先把按鈕拖上去,然后設置這個按鈕的事件序列,配置對應的事件。
3.把事件這個概念抽象並封裝起來
如“保存數據”這個事件,配置好數據的來源,如窗體上的數據,或系統數據,再配置好要保存的目標,某種數據實體,即可,這個事件被添加到某個事件序列,如按鈕的單擊事件序列中,項目被運行時解析時,就會按鈕這個邏輯執行。
4.對數據操作要有一定的自由度
除了基本的向導式配置以外,要能滿足特殊需求,比如支持自定義 sql 語句。但是自定義 sql 語句怎樣與數據源,目標交互呢?我設計了一種簡單的表達方法,如 UPDATE FROM [User] SET [Name] = {FormElement.txtName} WHERE [Id]={System.UserId}
5.對數據庫數據表的操作怎樣交互
就是將其抽象為“數據實體”,數據實體也在 IDE 中由用戶自己定義,定義的過程類似於 SqlServer,定義好數據實體以后,在 IDE 中進行設計時,通過數據實體來抽象對數據庫、表的操作,在打包項目時,可以根據定義的數據實體,生成多種數據庫,如 SqlServer,Mysql 等。
6.資源文件的管理
在項目中必然要引用到外部資源,這部分外部資源,怎樣引入,管理,打包呢?我在 IDE 中設計了獨立的資源管理器,在 IDE 中設計 UI 時,通過資源管理器引用資源,打包時,將資源打包到 zip 文件中。
7.打包前的靜態編譯檢查
類似於我們在 Visual Studio 中寫程序,編譯時如果有錯誤就會出現警告或錯誤提示。在這個 IDE 中,也必須有同樣的功能。當引用的數據實體被刪除,數據項不存在,引用的資源文件不存在,以及事件配置中一些問題出現時,能夠實時,並在打包項目時指出這些錯誤的具體位置。
8.支持嵌入腳本
能夠在事件序列中添加自定義腳本,支持在運行時動態解析或者調用某種腳本語言。此功能有所設計,但並未開發。
9.支持插件
此處插件支持指的是 IDE 層面能夠支持插件,類似 Visaul Studio 或者 Eclipse 的插件機制,我當時使用的是 .NET 管線技術(很冷門),實現了相關DEMO,但是沒有集成到IDE中。
10.IDE界面支持多國語言
目前IDE完整支持多國語言,所有文本均使用了資源,但是我沒有直接使用資源文件,而是將其強類型化了,具體實現方式下文詳述。
在設計開發這個 IDE 的早期,我並沒有給自己設定如此詳細的目標,現在寫其實更多的是回顧和總結。
在這個項目中,大量使用了 GDI+ 繪圖,說復雜,給你調用的接口也就那么多,說簡單,用 GDI+ 自己寫一個功能完備的 WinForm 控件,分分鍾教你重新做人。在這個項目中,幾乎所有的界面元素都是我自己用 GDI+ 繪制的,使用的第三方控件不多。后面我會寫一些這方面的感想。
下面羅列一些技術難點和主要功能點,有些細節可能沒有試着做過都不會意識到那是個問題。
1.工具欄按鈕/右鍵菜單的狀態控制
就是控制狀態欄上按鈕可用不可用,可見不可見,絕大多數時候這不是個問題,但是作為一個 IDE,工具欄上的各種按鈕非常多,且按鈕的狀態和當前設計器中的選中元素個數,選中元素類型,甚至選中元素自身的狀態等等相關,還有些按鈕是特定控件或元素提供的,怎樣統一控制這些按鈕的狀態?
黃色背景部分是動態掛載上去的,狀態的控制在后文中說明。
此處右鍵菜單指的是窗體設計器中的右鍵菜單,在窗體設計器中,右鍵菜單比較復雜,不同控件的右鍵菜單有所不同,有共通的項目,有特殊的項目,以及狀態是不是灰掉可能和控件本身的某些因素有關,但右鍵菜單本身是不可能通過處於設計狀態的控件自身提供的,所以此處如何把控件特有的菜單項掛載上去,又怎樣控制它們的狀態?注意設計器本身和用來設計的控件是解耦合的。
注意這個例子,右鍵 DataGrid 產生的右鍵菜單中存在“添加列” 和“編輯列”兩個特殊的項目。
此處當我選中 DataGrid 時,屬性網格下方也會出現這兩個項目,這里先提一個關鍵概念,叫做“謂詞”,這是一個 DesignSurface 中的概念,后文再詳述。
此處實際上我實現了一個獨立的菜單(包括工具欄項目)的管理器,並非直接創建 MenuItem 之類的實例去使用,這個管理器也是獨立於業務進行設計的,對菜單項的各種狀態,行為都進行了抽象與封裝。在管理器層面統一調度這些菜單項,通過一定的機制使菜單項的狀態與業務狀態關聯起來,不允許外部代碼直接修改菜單項的狀態,整套機制本身,與菜單項在UI層面的實現也是無關解耦的,最終生成可見菜單項時,才會生成特定的控件,如 MenuItem,也可以換成其它任何菜單項控件,不影響管理器的功能與邏輯。
我記得當時我研究了幾個IDE的設計細節,包括 Visual Studio,應該都采用了類似的機制,好吧我承認是我研究之后借鑒了它們的機制。
這個問題我放在首位,是我意識到這個問題在大型軟件中,真的是個很大的問題,我現在參與開發的一款電氣化CAD軟件中,就存在這個問題,但是他們早期並未意識到這個問題,也談不上能很好的解決,幾千個菜單項,工具欄按鈕項,直接硬編碼,對他們的狀態控制也談不上成體系,就是粗暴的硬編碼,現在的維護,修改,調整都異常痛苦。
2.窗體設計器
最初我是自己用 GDI+ 寫了一個簡單的設計器模型,支持拖拽,繪制,動態對齊等等功能,但是越往后越復雜,比如繪制一個 DataGrid,你不能光是一個框框,你要自己去繪制它的列,列頭,如果要繪制一個圖片框,你就要自己去繪制它的圖片內容,要考慮圖片的縮放方式等等細節,如果要一條道走到黑完全自己實現,成本將非常高昂。
先看看早期直接使用 GDI+ 實現的效果:
下面是直接使用微軟 DesignSurface 效果:
和 Visual Studio 效果一樣,不過這里需要注意的是 DesignSurface 僅僅也只是提供了基本的窗體設計能力(圖中右側部分),比我上面GDI+自己寫的功能多不了多少,但是不用自己繪制控件的外觀,其它輔助功能都是需要自行開發的。
這里要注意的一點是窗體設計器中 允許被設計 的控件 們,是與設計器本身,與IDE解耦的,是完全獨立實現的,后期添加新控件,修改控件都與IDE無關,這個地方的難點毅然是解耦合,各種解耦合。
左側的屬性列表是自行開發的,.Net Framework 中確實提供了 PropertyGrid 控件,但是對於高階開發此處並不適用,有很多制限,下文詳述。
3.工具箱
工具箱本身是獨立實現的,不依賴其所處的窗體設計器,同時它自身所承載的控件,也是動態載入的,后期允許第三方插件掛載控件到工具箱中。
這個地方需要注意的不多,一個是動態載入控件,另一個就是在和窗體設計器交互的時候,比如我拖一個控件到設計器上,這里是需要對接 DesignSurface 的。
4.屬性網格(PropertyGrid)
.Net Framework 中提供了 PropertyGrid 控件,可以實現對對象實例的屬性編輯功能,但是難於擴展與自定義,我此處需要個性化定制的地方比較多,所以選擇自己實現一個。
主要實現了以下功能
1)對於單個對象實例,列出它的屬性(Property,下同),以及屬性的值,如果屬性值與默認值不同,能夠粗體顯示。
2)對於特殊的屬性,提供對應的擴展編輯器,如顏色屬性,在點擊后應該提供一個顏色選擇器。且這些擴展編輯器,是與屬性網格本身解偶的。
3)如果同時設置了多個不同類型(Type)的對象實例,例如在窗體設計器中框選了多個控件,這個場景就復雜一些了;首先得到這些對象實例的類型(Type),抽取共通的屬性,屬性網格中僅顯示共通屬性,對於某個屬性的值,如果所有對象實例的值是相同的,則顯示,如果有所不同,則留空不顯示。在設置了某個屬性的值之后,能夠將新值設置到這些對象實例中。
5.撤銷重做引擎
這里可以用的上“引擎”二字,因為確實比較復雜,我們先將這個問題簡化,可以簡單理解為對“對象”屬性變化的跟蹤,可以撤銷這些變化,也可以重做這些變化,可以任意步驟的操作。
涉及到的問題和知識點很多,在 IDE 里對象狀態的變化又被抽象為具體的“操作”,以及這些操作又要和設計器進行聯動,有一定難度。
UI上的效果是直接使用 GDI+ 自定義的一個列表,並不是很復雜,其它能夠直觀看的界面UI不多,主要是代碼了。
6.事件及事件編輯器
上文中提到,要將常用的操作(事件)都封裝起來,通過配置的方式來運行,大方向好像並不復雜,但是,怎么做呢?首先事件本身的抽象要獨立,要與窗體設計解耦合,其次“事件”的定義應該允許由第三方插件擴展,甚至“觸發時機”也應該允許由第三方插件進行擴展。以一個最簡單的按鈕為例:
看上去和普通編程中的事件機制沒什么區別,是的,我們要做的是對其基本機制進行抽象化。例如:
1)觸發時機應該與事件寄主解耦,甚至允許第三方插件掛載觸發時機。
2)事件序列應該與觸發時機解耦,事件序列中的事件定義,應該與以上機制解耦,甚至允許第三方插件擴展。
看看項目中實現的效果:
我們就以“為窗體元素加載數據”這個事件為例,看看現在的事件編輯器大概是什么模樣。
這個事件支持“關聯數據實體方式”和“執行 SQL 方式”。
切換到數據實體界面中,選一個數據實體,然后設置相關的數據項。
這里就可以配置事件在執行時,從哪里取得數據,我們指定了從 用戶 這個數據實體中選擇數據,同時指定了一個條件,就是 用戶的 Id 要等於 指定文本框中的值。
除了使用界面元素中的值作為條件,還可以使用系統數據,如:
對於選擇特定的用戶,比如這個 Id 怎樣獲取呢?只要在加載數據時,把 Id 綁定到一個隱藏的文本框中就可以了,加載數據時,可以讀取它的值。
然后切換到載入界面
在載入界面中,指定我的數據取出來以后,加載到界面的哪些元素中。
我們上文提到,希望對數據的操作有一定的自由度,那么在事件編輯器中,就允許直接定義 sql 語句,或者說 sql 語句的模板。
切換到 sql 界面后,首先可以通過 獲取 sql 按鈕自動根據前面的配置生成 sql,然后在此基礎上進行調整,修改。
在 sql 編輯器中,可以通過 {Provider.Source} 的方式訪問數據。
支持語法着色,支持智能提示。
目前實現了兩種 Provider,FormElement (窗體元素)和 System (系統),在智能提示中支持遞進的提示。
所謂遞進的提示是輸入“{”之后自動給出 Provider,選擇后進一步自動給出 Source 列表。
也可以在 “{Provider” 后輸入“.” 則自動給出 Source 列表。
智能提示用起來簡單方便,看起來也很簡單,貌似只是一個 Popup ,實則是一個不小的坑,這個功能困惑了我很久,記得當時到處找大神請教,除了高談闊論的就是直接告訴我不知道,有個人也研究過 SharpDeveloper,告訴我這個問題深了,后來我又去翻 SharpDeveloper 的源代碼,參考了它的實現,完成之后還是相當有成就感的。
對於事件序列的編輯,有兩種方法,一種是在設計器中雙擊控件之后打開的事件序列編輯器
另一種方法是在窗體設計器中提供了以樹形方式展示的事件序列,可以直接拖動改變事件的觸發時機,或其在事件序列中的位置。
事件在解析器中執行時,是按鈕它所處事件序列中的順序進行執行的。
目前實現的事件大概有十幾個,基本的應用程序操作,數據交互等。
不再一一詳細說明,因為事件本事是在解耦的情況下獨立實現的,IDE並不依賴他們,所以未來擴展也很容易,可以說IDE和解析器是核心引擎,而這些事件定義,只是系統中的“業務”部分。
7.集合編輯器
集合編輯器,就真的只是用來編輯對象集合的,支持對集合中對象實例的編輯,以及集合中元素順序的調整,並且在與窗體設計器解耦合的基礎上,與窗體設計器聯動,能夠從窗體設計器中的元素取得對象集合,同時與撤銷/重做引擎對接,在編輯的過程中,提供撤銷/重做的支持。
這個編輯器完成之后復用性比較強,在窗體設計器中有很多地方需要對集合進行編輯,行定義,列定義,元素定義之類。
一個典型的使用場景是在窗體設計器中,對 DataGrid 的列進行編輯。
8.有效性檢查
在窗體設計器中,能夠對當前窗體中的各項設置,包含的事件進行有效性的檢查。例如我在某個事件中設置了加載數據到 TextBox1 ,后來我刪除了這個 TextBox1 ,那么就必須給出提示。
此處的主要難點應該在於解耦合,各種解耦合。
9.IDE多國語言實現
Visual Studio 自帶的資源文件編輯器使用起來不是很方便,比如多國語言,是分開在多個資源文件編輯器窗口中編輯的,沒有一一對應的顯示語言文本,另外直接使用資源文件,使用的是通過 String 做參數的弱類型方式進行調用的,不能做靜態編譯時檢查,也無法保證多語言相關編碼的質量。所以這里我沒有直接使用資源文件機制,而是進行了二次開發,我專門開發一個資源文件編輯器,提供一個一體化的界面同時編輯多國語言資源文件,使資源key同時和多個資源文件對應起來,同時支持導出excel,交給翻譯翻譯之后直接導回來,然后解析資源文件中的資源,生成一個統一的 ILanguage 接口,和不同的語言實現,如 class Chinese:ILanguage,class English:ILanguage,調用時,直接使用接口進行強類型調用,即將 Resource.GetString("buttonText") 變換為 _language.buttonText。
另一方面,實現了一種將界面文本綁定到資源的機制,這一點在 WPF 下非常方便,在 WinForm 下就要自己動手了。通過特定字符串標記資源key,在運行時自動掃描窗體或其它容器控件,通過解析這些字符串自動查找對應的資源,將其替換。
10.界面用戶數據的驗證
目前幾乎所有的開發平台都提供了比較友好的用戶輸入驗證方案,在 WinForm 下也有,不過並不是很完善,使用起來限制比較多,功能也有限,不是很順手。
我自己開發了一套用於 WinForm 的用戶界面數據驗證功能。舉個最簡單的例子,我給文本框設置一個不允許空的屬性,或者設置一個正則表達式,在我調用驗證方法時,就能夠對它進行有效性驗證。方案非常簡單,只是要花點心思把它實現好,各種控件都要支持,要解耦合,驗證器要支持多種不同驗證機制,驗證結果如何向用戶反饋等等。
這套驗證機制也同樣實現在了運行時(解析器)當中。
驗證結果的反饋並不一定要用 MessageBox,可以很容易的改進為其它更友好的形式。
11.模塊化設計
模塊化,插件式的框架設計現在應該有很多現成的框架和設計方法,但是在當時,又是 WinForm 下,可以參考的資料非常少,大方向不復雜,但是做完善做細致,在當時對我來說有相當大的難度。當時唯一可以參考的是微軟的 CAB 框架,但在當時來看,CAB 就已經是一個有些過時的框架了,使用起來有一些缺點和限制。
我在參考 CAB 的基礎上在 WinForm 下實現了一套分解的非常細致的模塊化開發框架,對軟件的功能進行層層解耦,宿主程序與功能模塊完全無關,而在我業務功能的設計上,IDE中的功能也實現了完全解耦,上文也多處提到了,窗體設計器與被設計的控件包解耦,事件機制與具體的事件定義解耦等等。
其它功能點
其它功能點主要是指:數據實體定義,主菜單定義,枚舉定義,資源管理,以及其它小功能等,下文先做個簡單展示,暫不再做詳細的說明。
1.歡迎界面
歡迎界面是內嵌了一個 HTML 頁面,只是和 C# 代碼有簡單交互,例如單擊鏈接會調用 C# 方法,並傳入參數。
使用 HTML 的一個原因是希望歡迎界面比較漂亮,但是在 WinForm 下實現一個漂亮的,交互性強,維護性強的歡迎界面有一定難度,很浪費時間。
此處注意一個細節, URL 地址不是一個磁盤文件地址,而是一個自定義協議和路徑的地址,這個需要自己實現,但是很簡單。
年代久遠,CSS 和圖片可能遺失了,不太好看,見諒。
2.數據實體定義
這塊相對比較簡單,沒有復雜功能。
發布項目時可以根據數據實體定義自動生成數據庫。
也可以針對指定的數據實體生成腳本。
3.枚舉定義
界面很簡單,生成數據庫時,根據枚舉定義向枚舉表插入枚舉數據。
但是有一個小細節是它和窗體設計器是有對接的,它是一個數據源的 Provider,可以在設計器中把控件中的值綁定到枚舉。
4.主菜單/工具欄定義
定義要生成的軟件的主菜單和工具欄,運行時解析之后,根據自己的實現方式生成,可以是 Ribbon 的,也可以是傳統的,或者其它方式。
菜單或工具欄項目支持事件,可以掛載事件序列。
5.資源管理
實現一個資源管理器,目前只實現了對圖片資源的管理。
這里有點看點的是,我當時沒有找到我覺得不錯縮略圖控件,於是只好自己實現一個。和 Windows 資源管理器功能一致,沒有需要特殊說明的地方,只是自己從頭實現一個不能說很難,但是真的很麻煩。借這個地方簡單講一下這個縮略瀏覽器的實現,可能有些朋友對 GDI+ 不是很了解。
對於在 WinForm 下使用 GDI+ 繪制界面(自己實現一個控件),是比較原始的,想像一下給你一張白紙,和一些簡單的繪圖接口,畫線,畫圓,畫矩形,其實沒別的了。畫一個圓角矩形?自己計算坐標系,通過畫弧線和畫直線畫一個。顯示一些文本?自己進行字體字號測量坐標系換算,如果涉及到文本換行,超長用省略號代替,都是比較麻煩的。
你要自己在 邏輯上 把握控件的不同狀態,如選中,非選中,鼠標滑過等等,和WPF下預定義的狀態組不同,WinForm 下這些狀態是你要自己去把握的,狀態切換時,你要自己根據狀態進行重繪……
在繪制界面時,你只有一個從0,0開始的二維的平面坐標系,和它的尺寸。實現這樣一個縮略圖瀏覽器,縮略圖的排版,布局,一行顯示多少個,什么時候換行,選中非選中,鼠標框選,滾動條滾動都需要自己實現,包括鼠標框選時的框,也是需要自己用 GDI+ 繪制的,然后自己計算坐標系,判斷哪些項目應該處於被選中狀態。
這個控件的代碼接近3000行。現在回過頭去看,只覺得注釋不夠詳細。
軟件中大部分自己實現的控件,都采用了類似的架構進行設計:控件本身,布局管理器,呈現器,呈現器實現,主題。
6.生成數據庫,生成項目
這里目前並不復雜,生成數據庫根據數據實體定義生成即可,生成項目目前我直接使用了項目文件,因為我目前的項目文件格式就是 zip 包,內含 xml 文件。
附帶產出是實現了一個簡單的比較通用的向導功能。
7.其它控件的美化。
從上面的截圖中能夠看到我使用了相當多的自定義控件,或經過美化的 WinForm 自帶控件,典型的幾個除了上面的縮略圖控件,還有IDE上面的主菜單(效果參考了 Paint.NET), DataGrid,重新實現的 ComboBox 等等,居然一步一步形成了一個自己的控件包。可惜技術更新換代日新月異,現在也基本用不上了。
IDE 部分現在回過頭去看,貌似實際功能並不多,但是核心架構已經基本完整了,后續如果繼續開發,基本相當於開發插件和添加新的功能包。
其中絕大部分是從空白 class 硬寫出來的,很多地方用現在的眼光去看,存在很大的過度設計問題。
解析器部分我是用 Silverlight 實現了一個,核心實現了,業務沒有實現完整,可能是我現在的機器 Silverlight 版本有問題還是怎么回事沒有運行起來,也不想去調試了,
並不復雜,只是解析 zip 包,xml文件,生成界面,事件處發時解析事件序列中的事件即可。
最后,如果你現在要做客戶端軟件,選擇 WPF 吧,生產性非常高,功能非常完善與強大,如果你擔心性能問題,我想說現在已經2015年了,不是2005年,如果你在開發中遇到了性能問題或其它問題,先從自身找原因。
專業程序員永遠從自身找問題,業余程序員從平台從語言找問題。
后記:
最后想寫一點點個人的感想與反思。我在開發這個軟件的過程中,犯了許多的錯誤,這些錯誤未必是技術上的,但都是嚴重錯誤。
首當其沖:閉門造車。活在自己的技術宅世界里,從來不去想,也不願意去想這個東西有多少實際價值,誰會去用它,到了后來,我明明潛意識里知道這個軟件沒有太大市場價值,就是不願意去想這個問題,一門心思去開發。我記得那兩年我隨身帶的手機里,記滿了關於這個軟件的想法和一些問題的實現思路。我在路上想到某個解決方案或者有什么想法,就立馬掏出手機記錄,怕回去就會忘記。有一個冬天住的地方沒有空調,非常冷,寫代碼一直寫一直寫,兩個手凍青了,就自己用熱水瓶子捂捂繼續寫,那段時間每到周末就特別高興,因為有2個完整的工作日可以利用了,不用單純靠晚上的時間去寫,很長一段時間我每天晚上我都只能睡四五個小時,個別時候還沒睡着,天就蒙蒙亮了。但是這么辛苦的意義是什么呢?我當時沒有認真的思考。
第二:目標非常的不明確。看上去有目標,我要做一個什么什么樣的東西,但是太宏大,太寬泛,太遙遠。沒有認真的考量我要的到底是個什么,所以完全沒有詳細的計划,里程碑什么都沒有。
第三:缺少與外界溝通。這個溝通除了技術,更多的是市場對技術的需求到底是什么,如果回到當初,我會抽自己一巴掌,你睜開眼睛,走出去看看別人的世界好嗎!做技術不是高新技術行業,更多的是服務業,我們需要利用手中的技術去為他人服務,這是技術存在的意義。
第四:不懂快速迭代,最小可用集。這個概念現在應該大家都知道了,在當年好像並不是很流行,也可能和我長期做企業級開發有關系,項目周期都非常長。做產品如果不懂得快速迭代是非常危險的,最小可用集就是只要達到最低可用的限度,就立馬拿出去見人,當然范圍可以是有限的。根據 真正 用戶的反饋,快速調整。這個說起來簡單,技術人員做起來很容易失控,我做這款軟件,就是花了大量的時間精力去研究技術方面的問題,以至於在某些方面挖的非常深,但是這個東西和我的 大目標 其實沒有必然關系,不管技術好不好,差一點就差一點,先做出東西來,先用起來,功能先實現,業務先轉起來,論證了這東西基本的可行性,再通過迭代去優化。
第五:做東西盡量不要藏着掖着。沒意義,藏着掖着無非怕別人剽竊了自己的創意,想法,這個先不論創意想法有多大實際價值,就算你的想法真的很厲害,如果你沒有其它門檻,別人看了就會抄去,那你這個東西一定是會出問題的。門檻這么低,怎么就你想到了?別算別人確實一時沒想到,你沒有其它門檻,被抄了是遲早的事情,藏着掖着沒有用。做了東西就要勇敢拿出來和人交流,正面的就吸納,負面的就多反思自己。
第六:開發這個軟件的過程中,我看完了《人月神話》,《代碼大全》,《設計模式》,和其它一些不是那么有名的書籍,一半以上 SharpDeveloper 源代碼。很多是在地鐵,長途車,火車里看的,當時好像沒有平板,有一次在火車上抱着筆記本電腦看《設計模式》,被旁邊妹子主動搭訕:“你是程序員吧”,想像一下,綠皮車,一堆人…… 上面講的幾本書我推薦有時間就看一看,特別特別是《代碼大全》,一定要看。我的體會是如果沒有目標,沒有目的的看書學習,很難深切領會,很容易泛泛而談,我當時看這些書大部分原因是被逼的,因為我總是遇到我搞不定的問題,我必須去尋求解決方案,比如設計模式,我當時也是被逼急了,有結構上的問題搞不定,就到處查資料,看書,一邊看一邊帶着目的的去想,這樣行不行,那樣行不行,這樣成長確實比較快。