1. 程式人生 > >使用 .NET WinForm 開發所見即所得的 IDE 開發環境,實現不寫程式碼直接生成應用程式

使用 .NET WinForm 開發所見即所得的 IDE 開發環境,實現不寫程式碼直接生成應用程式

直接切入正題,這是我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個完整的工作日可以利用了,不用單純靠晚上的時間去寫,很長一段時間我每天晚上我都只能睡四五個小時,個別時候還沒睡著,天就矇矇亮了。但是這麼辛苦的意義是什麼呢?我當時沒有認真的思考。

第二:目標非常的不明確。看上去有目標,我要做一個什麼什麼樣的東西,但是太巨集大,太寬泛,太遙遠。沒有認真的考量我要的到底是個什麼,所以完全沒有詳細的計劃,里程碑什麼都沒有。

第三:缺少與外界溝通。這個溝通除了技術,更多的是市場對技術的需求到底是什麼,如果回到當初,我會抽自己一巴掌,你睜開眼睛,走出去看看別人的世界好嗎!做技術不是高新技術行業,更多的是服務業,我們需要利用手中的技術去為他人服務,這是技術存在的意義。

第四:不懂快速迭代,最小可用集。這個概念現在應該大家都知道了,在當年好像並不是很流行,也可能和我長期做企業級開發有關係,專案週期都非常長。做產品如果不懂得快速迭代是非常危險的,最小可用集就是隻要達到最低可用的限度,就立馬拿出去見人,當然範圍可以是有限的。根據 真正 使用者的反饋,快速調整。這個說起來簡單,技術人員做起來很容易失控,我做這款軟體,就是花了大量的時間精力去研究技術方面的問題,以至於在某些方面挖的非常深,但是這個東西和我的 大目標 其實沒有必然關係,不管技術好不好,差一點就差一點,先做出東西來,先用起來,功能先實現,業務先轉起來,論證了這東西基本的可行性,再通過迭代去優化。

第五:做東西儘量不要藏著掖著。沒意義,藏著掖著無非怕別人剽竊了自己的創意,想法,這個先不論創意想法有多大實際價值,就算你的想法真的很厲害,如果你沒有其它門檻,別人看了就會抄去,那你這個東西一定是會出問題的。門檻這麼低,怎麼就你想到了?別算別人確實一時沒想到,你沒有其它門檻,被抄了是遲早的事情,藏著掖著沒有用。做了東西就要勇敢拿出來和人交流,正面的就吸納,負面