開發的技術細節本文就不談了,作者只想從感性上談談學習和實際開發WPF的感想。
首先祝大家新年快樂,小生給大家拜個晚年!
兩年前暑假,從百度百科上第一次了解WPF,被它的強大特性所吸引,當然最讓我着迷和期待的就是“絢麗”二字。兩年來,放棄了曾經的Winform開發知識,全面轉戰WPF,開發了兩三個大型項目,七八個游戲,和一些小型應用程序。也從當年的熱烈走向現在的穩重。因此,願意更從感性的角度討論關於WPF的一些感想。
本人只是在讀研究生,且並非計算機科班出身,因此不足之處請海涵。
MVVM模式的思考
以前開發winform程序,界面和程序是死死耦合在一起的,當修改了變量命名,改個樣式,或者做了一些其他修改(那會還不知道resharper),不得不花費很長時間來“擦屁股”,因此深之界面和邏輯解耦的重要性。
WPF很好的解決了這個問題,在設計之初就如此考慮,並引入了大名鼎鼎的MVVM模式。一開始不大了解,做得多了就懂了,一個ViewModel是不知道View的存在的,更利於分工合作,更利於單元測試。好處多得不得了。
可是,凡是總有弊端,MVVM確實適應於大量數據的展示,修改等“業務邏輯”,通過數據和命令綁定,觸發器等等的功能,可以很好的適應這種需求。可是,並非所有程序都是這種類型的,試想,開發一款簡單的游戲,你需要控制時間線,動畫效果,復雜樣式還有數不清的其他需求。此時,你會發現,除了直接用ViewModel操作View,別無他法。當然,如果硬要做分離的話,也可以,附加行為(AttachBehavior)就是干這個的,通過靜態依賴屬性,寫一個附加類來做這個,可惜,代碼復雜度成倍增加,需要較高的學習成本,把簡單問題搞復雜了。
因此,我想說的是,MVVM是個好模式,可是別太追求完美,千萬別撿了芝麻丟了西瓜,實在不行就耦合一下,這是一個很大的收獲。
綁定到弱類型的xaml
我和所有程序員一樣,喜歡強類型的安全感。
xaml綁定到了弱類型,好處在於更好的解耦,壞處在於沒有了編譯器和重命名工具的支持。我曾經用ReSharper修改變量名,從坐標名稱”X“改成”PositionX“,於是,整個系統被這個重命名搞得一塌糊塗,讓我修改了整整一天。運行時的綁定異常,比編譯時更麻煩,好在有snoop.
不過,這個沒辦法。慢慢適應吧。
到底是依賴屬性還是INotifyCollectionChanged?
常常需要在數據發生改變時通知界面(View)。於是便有了上面的問題。
依賴屬性真是個好東西,通過玩”靜態“二字,玩得真是漂亮。博客園里有不少介紹依賴屬性和附加屬性的文章,此處就不引述了。它算是WPF的根基,動畫,資源,綁定,無處不在的依賴屬性。
附加屬性更是神奇,可以把屬性記錄在別的地方,”附加“這詞用的很好。這讓人想起了裝飾器模式,動態增加屬性和行為,只不過屬性存儲在了別的地方。
既然依賴屬性這么強大,我們干嘛還累死累活的讓數據實現INotifyCollectionChanged接口?還寫一堆麻煩的數據更新通知?比如如下惡心的代碼:
private short _BreathRate; public short BreathRate { get { return _BreathRate; } set { if (_BreathRate != value) { _BreathRate = value; OnPropertyChanged("BreathRate"); } } }
這樣的代碼在WPF中無處不在,惡心死人。可是,如果用依賴屬性的話,也會帶來問題,有如下原因:
1. 依賴屬性的性能(肯定比原生的屬性要慢)
2. 依賴屬性不能跨線程訪問!包括讀!這個問題在多線程情況下真是要命
3. 必需繼承於DependencyObject, 這不僅讓你唯一的繼承機會喪失,還引入了萬惡的System.Windows命名空間,於是,你的未來代碼移植會造成極大地困難。
因此,我們有如下結論:
算法和底層數據結構:毫無疑問,讓它純凈一些,用INotifyCollectionChanged
界面相關:包括自定義控件,自定義效果等等,放心的用依賴屬性吧,絕對是正確選擇。
只有這樣,界面邏輯解耦的願望才能實現。
3D
WPF號稱支持3D,但我依舊要吐槽它,除了讓人無法忍受的效率問題,開發工具,教學資料的匱乏,都讓WPF的3D處於難以為繼的狀態。據我所知,僅有3DTools這些簡單的WPF的3D擴展工具,以及一些很簡單的輔助設計工具。用WPF開發3D,除非萬不得已,否則我不會用它。在這一點上,WPF完全可以向Unity3D學習。
第三方類庫
WPF是個界面庫,它天生就為良好的擴展性做好了准備。雖然不算多,但大部分需要的類庫都有了,Avalondock, WPFToolkit, 物理引擎庫,等等不一一列舉了。這些庫都比較新,不過很難看到WPF設計的完整軟件作品,起碼在國內看不到,他們都哪里去了???
性能
程序性能問題,是任何程序員都非常關心的。WPF的性能疑問,來自兩個方面,一個是動畫,一個是數據更新造成的UI更新。
我開發了幾個游戲,發現比較復雜的物體移動,總會出現卡頓,那種令人不爽的“虛”感。使用更快的CPU和獨立顯卡可以較好的解決這個問題,可是在3317U這樣的超級本平台上,程序運行起來風扇哄哄響,占用率達到一半。遠遠達不到unity3d這類3D平台上的性能和質量。同樣效果的flash動畫,也沒有這種卡頓。這到底是怎么回事?
在數據綁定上,我曾經懶惰的通過OnPropertyChanged(“”)的方式更新全部數據,但造成了嚴重的性能問題,因此建議僅更新對應的數據。
設計和美學
這是個復雜的問題,有專門的學科研究,本部分僅淺嘗輒止。
我的經驗,WPF在2D層面不限制你的任何想象力。但我有如下建議:對於一般軟件而言,避免不必要的花哨,提供統一直觀的UI效果是非常重要的,動畫等技術的存在,僅在於表達數據和信息本身,若造成用戶干擾,則有”炫技“嫌疑的東西可完全不要。Expression Design套件的設計對我們有很好的借鑒,黑色底色,淡灰色的文字,讓你專注於設計本身,而非工具。我們應該專注如何讓用戶更好的關注數據。
對於游戲或播放器等娛樂音樂而言,則設計思路有所不同。可以適當加入動畫,在配色等角度可以更活潑,但一定注意整體設計的協調,與主題的搭配程度非常重要。
設計是個復雜的事情,沒事可以逛逛很多平面設計論壇,都有很大的收獲。
前景?
打個疑問號,表示該問題值得討論。我沒有真正深入業界,因此本節僅供參考。
06年WPF技術公開,在08-09年貌似達到高峰。據我所知,博客園的絕大多數關於WPF的文章都是這個時期發布的,Blend等工具的出現,大大改進了界面設計方便性。但貌似,我這個軟件控也沒有看到除了微軟這套Studio之外的,任何以WPF開發的商業軟件系統。360,QQ,各類音樂播放器等等都沒有,只有QQ概念版基於WPF,可是之后也沒有更新了。究其原因,大概是需要安裝.NET 3.5甚至4.0以上版本,部署起來不甚方便。也與當前程序普遍WEB化不無關系,
但我依舊疑問,為什么在2010年之后,博客園很少有系統的WPF開發文章了?為什么到現在都沒有客戶端的WPF系統?它的前景究竟如何?
不過,學WPF一點都不虧,xaml,數據綁定,和AE,PR類似的時間線系統,和絕高的開發效率,這些知識可以很快的轉移到其他相關領域。
結語
說了這么多,沒用圖片,也沒拷貝大段代碼,就是簡單的聊聊。只是,在如今WEB化和移動化大行其道的情況下,windows桌面程序開發的價值又有幾何?這難以估量,不過作為程序員,學習它,一點都不虧。
本文的任何見解, 歡迎大家討論。