从 API、UI、结构到商业产品设计精髓
本文來自作者?范蠡?在?GitChat?上分享「Windows 程序設計精髓:從 API、UI、結構到商業產品」,「閱讀原文」查看交流實錄
「文末高能」
「更多同類話題」
「查看全部話題」
編輯 | 朝偉
當下,Android、Linux、Mac 等設備也大行其道,PC 軟件似乎已經日薄西山。
然而,我們大多數人平常工作、學習、娛樂的環境都是Windows平臺,仍然在使用 PC 機器上各種軟件,即使從事 linux 開發的技術人員,也很多使用像 xshell/SecureCRT 這類支持 SSH 協議 pc 軟件遠程登錄到 linux 機器上來操作,實際工作的平臺仍然是 Windows,使用的軟件仍然是pc軟件。
我接觸 Windows 開發有十多年了,先后擔任過像股票行情資訊系統、手機助手等多 款 PC 軟件的主程工作,也“客串”過 PC 端軟件的產品經理,對用戶使用 PC 端軟件的行為習慣和用戶心理有一定程度的了解。
本文 將 PC 軟件開發中涉及到的 Windows API 編程技術、界面庫、程序庫、框架結構設計以及商業 PC 產品設計思路等方面來分享我的經驗。
內容包括 Windows 軟件開發需要掌握的技術和產品理念,希望對從事 Windows 軟件工作的開發人員和產品人員有一定的幫助和啟示。
這里說明一下,這篇文章討論的內容不是 Windows 程序的具體編碼細節,而是 Windows 平臺上從程序設計到產出一款商業軟件的方法和思想理念,當然這種思路也適合移動端等其他客戶端軟件。
一、Windows程序的特點
1. 嚴謹的接口設計
按操作系統的技術棧發展來看,相比較類unix操作系統比較短小精悍的命名風格,Windows 操作系統提供的函數接口以及各種函數參數的命名都是很清晰而已容易看懂的。
雖然古怪的匈牙利命名法(下文將介紹)讓 Windows 程序看起來有點“中世紀風格”,但這種命名方法增加了 Windows 程序的可讀性和可理解性,后來者也不斷模仿之。
首先,Windows 提供的函數名稱、結構體類型風格都非常統一,諸如CreateProcess、CreateThread、CreateMutex、CreateSemaphore等。
當然也有例外,比如堆創建函數 HeapCreate,這個據《The Old Things of Windows》(中文名《Windows編程啟示錄》)的作者Raymond Chen說,當時設計這個堆系列的接口函數的是微軟另外一個部門,所以風格出現了不一致- -!
擴展的函數和結構體在原有的基礎上使用 Ex,例如從 CreateWindow 到CreateWindowEx,RegisterClass 到 RegisterClassExWNDCLASS 到 WNDCLASSEX。
新的擴展的接口不僅兼容舊的接口的功能,還增加了另外一些新功能新特性,如果您用不到新的功能和特性,仍然可以使用舊的接口函數。
Windows 在新舊系統兼容性方面做的也非常優秀,即使在最新的 Windows 操作系統上使用很老的 Windows api 仍然沒什么問題。
雖然很多api或者做法不推薦在新版系統中使用,但是你使用它們仍然不會有什么大問題。
反觀,現在的一些操作系統比如 Android,低版本使用的API一個個被棄用,原來老的做法在新的系統上可能會導致程序直接crash掉。
再者,Windows 將大多數資源抽象成句柄(HANDLE),例如socket、進程對象、線程對象、畫筆畫刷對象,甚至連像Windows服務這樣的東西也抽象成對象。
這種抽象帶來的好處就是可以用同一套邏輯去處理,比如操作一個對象必須先打開或者創建,然后使用,使用完了之后然后關閉。當權限不足時也不會因為越權而帶來安全隱患。
2. 匈牙利命名法
在駝峰式(例如myBestFriend)、帕斯卡(例如MyBestFriend)或者連字符式(例如my_best_friend)等諸多命名法當中,匈牙利命名法是Windows程序的一大特色。
雖然顯得很奇怪,但是帶來的便捷性和可讀性不得不提。匈牙利命名法是比爾蓋茨雇傭的第一代程序員查爾斯·西蒙尼發明的(Excel的主要開發者),這是一個傳奇性的人物。
匈牙利命名法的主要思想是給程序變量加上它的類型信息,例如一個表示數值的整形變量,可以叫 nNum或 iNum,表示屏幕尺寸的整型變量可以叫 cxScreen、cyScreen,以 NULL 結束的字符串指針叫pszStr(sz的意思是String terminated with Zero,以0結束的字符串)。
當我們在代碼中看到這樣的變量時我們無需查看其類型定義。網上有很多論調說這種命名法已經過時。但筆者以為,這些觀點難免有點以偏概全。
在后來的很多系統設計上,很多地方可以看到匈牙利命名法的影子。這種命名法雖然看起來很拖沓,但是表達意思卻是非常清晰。
尤其是在閱讀別人的項目代碼或者維護一些舊的項目時,能讀懂是維護的前提。
3. 消息機制
之所以把Windows消息機制單獨列出來是因為基本上可以認為它是以后所有的操作系統界面的模型的先驅,同時也是我們普通程序開發者應該學習和模仿的典范。
它本質上就是一個消息隊列,Windows消息隊列的實現可以參考開源版本的”Windows”——ReactOS。
ReactOS開發團隊立志要做一個與微軟 Windows 一模一樣的操作系統,這里說的“一模一樣”不僅指的是 ReactOS 的界面和使用習慣與 Windows一模一樣。
甚至連提供的操作系統接口函數的名稱、簽名都必須一模一樣,而且參與開發的人員必須沒有閱讀過任何 Windows 源碼哪怕是微軟泄露出來的代碼也不行,如果發現這種情況,立馬開除,并且立即重寫被開除的人的所有代碼。
所有關于 ReactOS 的實現都必須通過逆向 Windows 來獲得。所以ReactOS這個項目最大程度地仿真了 Windows,并可以免費開源。
回到正題上來,這里要提一下的是,消息隊列是軟件產品中非常常用的技術,所以如何設計出一個好的消息隊列屬于開發者的基本功了。
Windows可以參考,現在流行的很多專門的消息隊列框架(如RabbitMQ)都是不錯的學習資料。
4. 統一的用戶界面使用習慣
Windows 程序除了一些自繪的界面以外,大多數界面風格、菜單位置、使用習慣等都是一致的,例如如果某個菜單項后面有…(三個點),點擊該菜單項一般都會彈出一個對話框;
對于文本的編輯操作(例如復制、剪切、粘貼)等一般統一放在”編輯”菜單下面。
這也是 Windows 和linux的不同,Windows 的哲學是假設你不會操作,Windows教你如何操作;而linux是假設你會操作。
所以,廣大產品人員在設計UI的時候千萬不要違背這種微軟培養出來的多年用戶習慣,否則您的用戶很可能因為覺得您的產品操作非主流而放棄使用。
二、Windows下的界面庫與自繪技術
一些應用軟件為了追求一些特殊的界面效果,需要展現出不同于傳統的Windows程序界面的樣子(比如游戲界面)。由于Windows操作系統提供了最大化的界面自繪接口,所以市面上出現了很多開源的或非開源的、收費的或非收費的界面庫。
核心思想其實就是調用Windows GDI或GDI+函數進行自繪,GDI提供的自繪接口在一些追求界面細節的精細程度上做的不夠且GDI接口都是C接口不符合現在開發軟件使用的面向對象模型的理念,所以后來微軟又專門推出來一套基于GDI的純面向對象的繪制接口GDI+(GDI Plus),更不用說專門用于圖形要求更高的領域的opengl、direct3D了。
比較著名的開源的界面庫像DUILIB,這個庫最先由一位德國人開發,后面中國的一些開發者接手,產生了種類繁多的分支。
微信和百度云盤的pc客戶端都是基于DUILIB。收費的界面庫像迅雷的bolt。這里不再列舉各種界面庫的名字了,無論哪種界面庫其核心技術都是自繪。
這里不得不說一下這里的DUI思想,做Windows界面開發,這是一種必須理解的界面繪制思想。
所謂DUI,即Directly Draw on Parent,即子控件對象直接繪制在父窗口上,也就是相當于只有父窗口一個窗口句柄。
原來可能每個子控件都是窗口,windows消息機制決定,窗口越多,窗口的消息泵也就越多。
為了減少這些消息泵,子窗口直接繪制在父窗口上,然后利用PtInRect這類API函數去檢測鼠標是否位于這些繪制出來的控件上,然后利用PostMessage/SendMessage等API產生消息,交給父窗口處理,以此模擬這些無窗口句柄(hwndless)的控件可以響應消息的效果。
衡量一個界面庫的優劣不僅要看這個界面庫的功能,也要看它的流暢性(性能)和用戶友好性程度。
騰訊QQ從2009版本開始,采用了這種思想,到今天的2017版本,其界面的設計是一個經典的范例,而2009版本也是QQ應用DUI思想,UI產生質的飛躍的一個轉折點。
當然個人覺得界面庫就該做好界面庫自己的工作,現在一些界面庫的作者因為一些利益的驅使,在其發布的界面庫里面包含了方方面面的功能,核心的界面功能不去優化,一些與界面有關的類對象,因為繼承鏈的關系,體積已經達到幾十k甚至更大,并號稱“旗艦版”。
這很容易對一些初學windows界面開發的新手造成誤導。界面是客戶端軟件的臉蛋,也是用戶體驗好與差的第一衡量標準,一個用戶體驗好的軟件界面是開發人員、產品人員和美工人員共同努力的結果。
三、Windows 上的程序庫
Windows上的程序庫最經典的當屬mfc(Microsoft Foundation Class)。網上有大量的言論說 mfc 已經過時,mfc 很臃腫。
這里我有必要澄清一下,根據我個人的學習成長歷程來看,學習Windows程序設計正確的順序是先學習 Win32 API,然后學習 mfc 框架。
mfc 可能不是一個最好的框架,但一定是最好用的框架。當然學好mfc是一個先易后難再易的過程。
mfc 的很多設計理念和思想都是非常優秀的,比如消息路由、C++對象的序列化與反序列化、動態創建、視圖/文檔對象模型等等。
在后來者的各種軟件框架當中都能看到似曾相識的影子。從另一個角度來講,每個開發者可能都想成為程序架構師,而一般都是從學習模仿別人的框架開始,也就是說你的腦中應該有一些經典的框架設計。
那么mfc可能是你學習成本最低、收獲最大的框架。君不見Qt為啥也要抽象出QtApplication這樣的對象?桃李不言,下自成蹊。
有人說mfc很臃腫,這點mfc真的很冤枉。mfc之所以臃腫是因為它是作為一個面面俱到功能型的程序框架,最大程度的去讓使用框架的人減少重復勞動并快速生成一套可以使用的軟件。
功能多了,生成的庫文件也就相對來說大一點。當然在現今的磁盤容量、內存容量、網絡帶寬條件下,mfc那幾兆的庫文件其實已經微不足道了。
當然,如果你不需要mfc這種重量型的框架,你可以使用WTL。WTL是基于C++模版的,程序庫都是一些頭文件,嵌入到你的程序中進行編譯,本身沒有任何二進制庫文件。
WTL沒有mfc那樣的方方面面的功能,只是將一些與窗口(包括控件)相關的東西封裝起來(當然也包括一些常用的工具類)。
市面上有很多軟件都是基于 WTL 做的擴展,例如360安全衛士、金山衛士等等,我的開源即時通訊軟件 flamingo pc 客戶端也是基于WTL做的一套自繪界面庫。
近些年,隨著移動設備安卓、IOS的流行,Mac機器和linux平臺也開始受到很多用戶的歡迎。
很多軟件開發商為了減少開發成本、縮短開發周期,一套程序可以同時運行在多個平臺上,Qt這樣的跨平臺框架流行起來。但是Qt這種龐然大物以及它的學習成本,筆者實在不敢恭維。
總結起來,不管哪種程序庫,一般適合自己的軟件項目才是最好的,沒有必要為了使用框架而使用框架。
在我帶隊的公司最近幾個pc端項目都是我仿照 mfc 的思想用 Win32 API 從底層開發的,沒有使用任何現成的框架。
鑒于此,廣大開發者或者公司決策人員,在做產品技術選型時,要綜合考慮多方面因素去選擇一款合適的程序框架。
四、PC 端軟件的組織結構、架構設計
關于PC端軟件的組織結構和框架設計,最核心的其實就是界面邏輯和數據處理,數據處理可能是一些復雜計算或者網絡通信。
最經典的也就是三層結構,即UI層、數據加工層和網絡通信層。
關于它們的具體細節,我在我的另外一篇文章《客戶端軟件的結構思考》中詳細地介紹了:。文中有具體的細節和具體的案例分析,有興趣的可以參考一下。
五、商業 PC 產品設計思路
這個話題如果展開來說,是一個非常大的話題。這里我就具體而微的來說一下我的經驗。
一款成功的商業軟件,在開發之前要做可行性分析和競品分析。如果你的軟件目前市面還沒有,那么你在決定開發之前要對它做可行性調研,諸如開發技術難度、開發周期、是否有市場需求、盈利點等等都應該是重要的考慮因素;
如果你的軟件目前市面上已經有了,那么您需要做競品分析時,您要吸納采用同類軟件的優點,反思同類軟件的不足用于改進或者完善自己的產品。
我曾經帶隊開發過一款郵件采集與加工系統,用戶是某知名基金公司的研究員們,他們會將原創的各種金融研究報告匯總至指定郵箱。
這款軟件就去從該郵箱讀取這些郵件,并解析出來,然后生成對應格式的報告在金融平臺上展示,程序需要自動識別郵件的標題、發件人、分組、郵件主題等內容,還要自動處理有附件的郵件。
這款軟件的業務其實并不復雜,但是在海量數據的處理的性能上,以及自動處理和加工郵件的內容是一個重難點。
所以我在和產品人員溝通時,也會重點就這些方面的細節做好一一溝通落實,在開發人員的安排上也會往這些方面做一定的傾斜。
商業軟件的另外一個問題就是程序的發布方式,這包括兩個方面:
1. 程序的發版問題
對于一些安裝體驗要求不是很高的軟件,目前像 NSIS 或者 InnoSetup 這樣現成的打包工具已經足夠用了,當然如果您需要獨特的安裝程序,您可能需要自己去開發。
安裝程序本質上是檢測軟件所在的運行環境、釋放程序文件到指定位置以及寫入一些初始化信息或配置信息去注冊表和配置文件中。
2. 程序的自動升級問題
考慮到程序的bug修復和新功能的后續更新,大多數客戶端軟件都可以自動升級。
當然蘋果的App是行業內的一個奇葩。所以為了你后續的商業利益,自動升級這個功能一定是要特別重視的。
只要自動升級功能不出問題,無論您的軟件當前如何,您都有“補償”或者改進的機會。
商業軟件的另外一個需要注意的是,就是用戶體驗問題。良好的用戶體驗,能讓用戶對您的軟件產生依賴。
反觀一些軟件,一些常用的快捷鍵要么沒有,要么非常難記難用。這都是經典的反面教材。
限于筆者水平和經驗有限,文中難免有偏頗之處,歡迎提出批評指正意見。
近期熱文
《TensorFlow 計算與智能基礎》
《突破技術發展瓶頸、成功轉型的重要因素》
《Selenium 爬取評論數據,就是這么簡單!》
《這種稀缺的測試人,好多公司都搶著要》
《Node 企業項目大規模實踐》
GitChat 與 CSDN 聯合推出
《GitChat 達人課:AI 工程師職業指南》
「閱讀原文」看交流實錄,你想知道的都在這里
總結
以上是生活随笔為你收集整理的从 API、UI、结构到商业产品设计精髓的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 优学院中国近现代史纲要试题及答案
- 下一篇: 马赫效应和应对方法