年初,我和某家IT雜誌社編輯一同參加一場某軟體廠商舉辦的會議。主講人在臺上展示使用該廠商技術開發出來的漂亮介面,相當吸引人。編輯看了之後,頗為讚許,轉身對我說:「這東西很棒吧!」我澆了她一盆冷水:「要做到這樣的GUI(Graphical User Interface,圖形使用者介面)效果,複雜度相當高,背後投入的資源相當多,可不是一般小公司做得出來的。」對於GUI程式設計,我的考量點一直都不是「能不能做得到」,而是「容易做得到嗎?」。
對許多人來說,學習一個新的編程語言不難,只要學會數十個關鍵字(keyword)的用法,了解程式模組、迴圈、分支、物件導向的語法,就可以開始寫程式了。語言本身並不困難,真正難的地方在各種領域的API(Application Programming Interface,應用程序介面),其中又以GUI的API最複雜。
我有資格這麼說,是因為在我的Java狂熱期,我幾乎學過用過所有官方的Java API,其中最複雜的不是EJB,而是Java Swing(Java的GUI API)。我將所有Java Swing原文書都買回家(其中許多本都超過一千頁),一本接著一本詳細閱讀,也寫了不少程式,幾年之後,才能對它「完全」運用自如。這段期間我也花了不少精神在Java 2D API與Java 3D API上。
在Java之前,我學過Win32 GDI、MFC、OWL;在Java之後,我用過WinForms、GDI+,也接觸過Flex、WPF,它們全都是複雜的GUI API,但是其複雜程度,還是比不上Java Swing。
如果像我這樣喜歡GUI程式設計的人,都覺得GUI API太複雜的話,對於那些沒有投入許多時間到GUI的人來說,GUI根本就是開發軟體的一大障礙。
難道GUI程式設計都沒有什麼進化嗎?勉強算是有一點點。近十年來,在GUI設計上,經歷過三個主流階段,分別是:(1)C語言介面;(2)元件化;(3)XML化。
在C語言介面的時期,任何動作都是透過C的函數呼叫,程式寫起來相當囉唆,也大量使用函式指標當作回呼函式(call-back)。
到了「元件化」時代,我們用C++、Java、C#……等OOP(Object-Oriented Programming,物件導向編程)語言編寫GUI。通常我們會透過雙向(2-way)GUI設計工具(例如JBuilder、Visual Studio)的協助,讓我們可以用拖曳(drag-n-drop)的方式,產生出程式碼。
對於這種自動產生出來的程式碼,我們最好不要徒手修改,否則可能會造成雙向GUI設計工具無法了解程式碼。因此,像JBuilder這樣的工具會將產生的程式碼獨立於建構子(constructor)之外,放在一個專門的jbInit()方法內,並希望編程員不要徒手修改此方法。
上面這種作法的缺點是,將GUI設計和程式邏輯混雜在一起。GUI設計和程式設計是不同的專業領域,最好分開由各自的專家負責。除此之外,GUI的設計也比較偏宣告(declarative)的方式,而不是主流語言使用的命令(imperative)方式。
於是在「XML化」的時代,WPF和Flex的作法,允許我們將GUI設計的部分獨立出來,使用XML來描述(而不是使用編程語言)。XML可以當作描述語言,但有一些嚴重的缺點:(1)XML檔案不適合徒手編寫,最好要有工具的協助;(2)XML程式碼相當冗長,會使檔案大小暴增。(3)XML缺乏彈性,適合用來描述結構性的資料,但不適合描述以外的東西。
上述的進化過程,廠商都是利用「GUI設計工具」來簡化GUI開發過程的複雜程度,而不是從根本簡化GUI API著手。
因此,如果沒有「GUI設計工具」可用的話,根本沒有人有能力寫出像樣的GUI程式。加上主流GUI API不斷地改朝換代(例如MFC->WinForms->WPF),更是讓我們疲於奔命,剛熟悉一套API,又要開始學新的API。
有些人則以不變應萬變,使用外部套件如:Tk,不管什麼語言、平臺,都可以透過橋接器使用Tk。但是像Tk這樣的GUI套件往往太僵化,且不美觀,做出來的GUI效果並不吸引人,甚至和OS的GUI差異太大,畫面反而看起來顯得詭異。
由於GUI API的實做和OS的關係相當密切,能跨平臺的部分不多,所以許多開放源碼的語言,並沒有足夠的資源做一套自己的GUI API,只好橋接到像Tk這樣的GUI套件,儘管不合適,也只好將就著使用。以Erlang來說,至今還沒有一套令人滿意的GUI API可以使用,於是內定使用Tk,但其實Erlang和Tk的設計理念根本是不搭的。
不管使用什麼語言,只要需要開發GUI,就會讓我頭痛一陣子。而短期內,這似乎沒有解藥。
作者簡介:
蔡學鏞-技術顧問
清華大學資訊工程碩士,曾任華碩集團軟體工程師、元智大學資訊系講師、美商歐萊禮出版社技術編輯、臺灣微軟特約專欄作家。
熱門新聞
2024-12-16
2024-12-16
2024-12-17
2024-11-29