標籤:
前言:我打算寫一系列關於Swing程式開發的文章。這是由於最近我在做一個Swing產品的開發。長期做JavaEE程式,讓我有些麻木了。Swing是設計模式的典範,是一件優雅的藝術品,是一件超越時代的產品!有機會作Swing軟體的開發,讓我非常有感覺!呵呵,希望有機會能夠用Java3D編寫軟體,那種感覺一定更棒!Java和Swing都是傑作。我這個人對別人一向很挑剔的,能夠得到我由衷地讚譽,可想而知它們有多優秀了。奇怪的是,它們居然一直都無法佔領案頭市場。有人說這是技術的原因。我認為這應該是商業、曆史的原因才對。好了,我也應該為java和Swing在案頭的成功盡我綿薄之力,共用我的思想吧!以感謝這麼多年來,Java帶給我的美好回憶。檯燈、電腦、Java,還有Coffee,伴我度過多少不眠之夜!I love U!
Swing
程式最佳架構設計之一
業務模型中心架構模式
以業務模型為中心以業務模型為中心的架構模式。這是Swing和其他所有程式應該採用的架構模式。之所以強調Swing,是因為在Swing程式中使用這種“以業務模型為中心”的架構模式,更有意義,作用更大!我們知道,一個軟體由幾個部分組成:1,表現層(使用者介面層)這時軟體和使用者互動的部分,可以分為字元介面(DOS等命令列),GUI圖形介面(案頭GUI,瀏覽器GUI,三維介面)等。這僅僅是軟體的外表,外貌再華麗,也不能說明軟體的優劣!Google的介面平淡無奇,但它確是今天最強大的軟體! 2,業務層這是實現軟體功能的地方。存在著大量映射著業務領域的對象,存在著複雜的業務計算。這才是軟體真正工作的地方。軟體的核心和痛點就在這裡!巨大的開發工作量和思考,也都集中在這裡。業務模型,及其互相之間的互動,這才是軟體的核心! 3,資料庫訪問層(可能有)有些軟體需要把操作儲存進資料庫,持續保留下來。通常,企業級等需要業務資料的軟體需要這個模組。它實現業務對象和關係型資料庫的映射。稱為“O-R”映射。 4,持久化層(可能有)有些軟體不把資料儲存進資料庫,而是儲存為檔案。如,二進位檔案,文字檔,XML檔案等。它實現業務對象和檔案之間的映射。可能是序列化業務對象。如果是儲存為xml檔案,我們稱它為O-XML映射,是業務對象和XML檔案之間的映射。現在有一些開源軟體實現了Java對象和XML檔案之間的映射,就如同是O-R映射一樣。其實,基於Java的XML訪問組件,自己開發O-XML映射也是非常簡單的,我自己也寫了一個這樣的庫。 可以看到,“以業務模型為中心”,並不是一種特例,而是最基本的軟體開發規律!是所有軟體共有的基本特性。只是,今天,在各自不同的領域,這個基本常識被一些常用的領域中的架構模式所模糊了。如,在Java的企業級軟體開發中,大家都知道J2EE軟體分為3層:1,表現層2,業務層-----業務對象和Service助手類3,資料庫訪問層-----DAO助手類這樣的架構模式,模糊了“業務對象”是整個軟體的核心這樣一個事實。Service助手類和DAO助手類,實際上都是業務對象的一部分,完全可以被放在業務類中。助手類和業務對象分離,不過是一種設計模式而已。
Swing程式中的應用好了,本文並不想討論這些“形而上學”的問題。上面的討論,不過是想讓你明白,本文所論述的“以業務模型為中心”的架構模式,並不是Swing應用程式所特有的,而是所有軟體的特性,只是,在Swing這個條件優越的案頭開發環境中,更加有用罷了! Swing程式作為傳統型程式,擁有比JavaEE程式更好的環境,更強的功能。Swing程式常常是單機的,即使是網路化的,也可以在業務層中實現分布式,而不像JavaEE程式,使用者介面和響應使用者操作的代碼都是分布在不同的機器上的!因此,Swing程式更能發揮我們軟體開發人員的智慧和能力!
Swing
程式最佳架構設計之二
MVC
模式
Swing程式的組成一般,Swing程式由以下幾部分組成:1,表現層----Swing組件組成的GUI2,業務層------業務對象,及其相互之間的關係3,持久化層-----把業務對象儲存為檔案,或者是資料庫記錄。
MVC模式在Swing程式中的應用我們知道,Swing是MVC模式的典範。Swing的各個可視化組件都使用MVC模式來設計。
Swing組件一般由三個部分組成:1,Swing的Model,這是MVC中的M—模型部分。它儲存了Swing組件所需要的資料。Swing組件的UI需要根據它來展現。2,Swing的UI類。這是MVC模式的View—視圖部分。它根據組件的Model中的資料,執行繪製、展現Swing組件的任務。3,Swing組件類。這是“門面”,它封裝了Swing的UI對象和Model對象。我們一般都是通過它來操縱Swing組件,不會直接使用Swing組件內部的UI對象和Model對象。Swing組件之間,還有著複雜的關係。Swing的UI類,監聽Model對象的資料改變,即時進行重繪介面的工作。在Swing組件上還可以註冊一系列的事件監聽器。它們就是MVC模式中的Controller控制器。
Swing應用程式中使用MVC模式一個Swing應用程式的GUI由很多個Swing組件組成。各個Swing組件本身是由MVC模式設計的,而我們的整個Swing應用程式的表現層也應該由MVC模式設計。使用MVC模式,能夠更好地分離代碼和資料。使整個應用的表現層部分,更加低耦合、高內聚,靈活度更高。在Swing應用程式的編寫過程中,我們需要使用Swing組件的2個部分:1,Swing組件的Model。Swing組件的MVC模式設計,使整個Swing組件是以Model為核心的。通過更改Model,我們就能夠即時改變Swing組件的UI外觀。2,Swing組件上註冊事件監聽器。這是Swing組件的控制器,也可以作為整個Swing程式的控制器之一。 在Swing組件的監聽器中,我們可以響應使用者的操作,作為整個程式功能的入口。在這裡,我們可以調用業務層的代碼進行業務計算。計算完畢之後,可以修改Swing程式的外觀。常常是修改某個Swing組件的Model。 Swing組件的監聽器,一般是使用Swing程式的內部類來實現的。因此,我們可以在控制器中完全使用整個Swing程式的所有資源!因此,Swing組件的控制器是足夠足夠強大的!
此Model非彼Model讀者應該對JavaEE比較熟悉吧。畢竟,今天Java的主戰場是在企業級應用上,會java,而不懂javaEE,這就有點說不過去了。這裡,我以大家比較熟悉的JavaEE的表現層技術來說明Swing程式的MVC設計。
Struts中,其MVC由以下幾部分組成:1,View視圖,就是使用Struts標籤的JSP頁面。2,Controller控制器,就是響應使用者操作的Action。3,Model模型,就是使用者html頁面表單中提交的資料。這在Struts中被稱為“form”表單。HTML表單的資料,都是String型的,而我們的業務對象的屬性,卻未必都是String型的。因此,在Struts應用程式中,我們需要根據接收到的form對象,構造業務對象。在SpringMVC中,提供了一個機制,可以協助我們自動把表單資料轉為業務對象。對於一些特殊的類型轉換,還是需要我們手工提供轉換。Form和業務對象之間的自動轉換,固然是提高了開發效率。但是,我們必須要明白,GUI組件中的資料Form和業務對象是截然不同的兩種東西。2者碰巧一樣,或者可以自動轉換,只是特例。它們本質上還是兩樣截然不同的東西。Form是表現層的資料容器,而業務對象則是來自於特定業務的對象。Form的資料類型,變化不多,而業務對象的資料類型,那就是千變萬化了。因此,Form物件類型和業務物件類型一致,這是少之又少的特例。
Swing程式中的表單資料(Form)和業務對象(Model)Web應用程式中的表單資料form,是來自於Html的表單的各個項的資料,都是String類型。Swing程式中的表單資料Form。是由Swing程式的各個Swing組件的Model組成的。其各個部分的資料類型非常不同。如,最簡單的文字框JTextField的Model,是javax.swing.text.Document類型的對象。這個對象,我們也可以直接得到或設定String的值來作為Model。實際上這個String類型的資料,是Document的屬性。還有,如JTree組件的Model是TreeModel對象。因此,Swing程式中的表單資料Form的類型是非常多的。顯然,我們的業務對象不大可能和Swing的Form資料的類型一致。因此,Swing程式的表現層的資料Form和業務對象Model之間的轉換,必然要由我們自己去實現。不大可能直接把Form作為業務對象扔到業務層中使用。也不可能直接在Swing的GUI中顯示業務對象的資料!
Swing程式的MVC模式的使用整個Swing程式應該這樣使用MVC模式:1,JFrame或者其他頂層容器中,由各個Swing組件構成了View視圖層。用來展現資料,提供使用者操作的圖形介面。 2,一個或者一組業務對象是Model。它們存放了Swing組件要顯示的資料。它們是業務對象,因此,可以直接在業務層代碼中使用,執行複雜的業務計算。它們不能直接在Swing組件中顯示。而是需要根據業務對象,構造Form對象,也就是Swing組件的Model來展示資料。為了讓View—Swing組件即時展現業務對象的資料,我們需要讓Swing組件監聽業務對象,一旦業務對象發生改變,就重新根據新的資料,構建新的Swing組件的Model,從而在Swing組件上展現最新的業務對象資料。這裡,我們使用ChangeListener改變監聽器。為了讓業務對象能夠得到使用者最新輸入的資料,我們還需要將業務對象註冊到Swing組件上。一旦Swing組件的資料發生了改變,就通知業務對象。業務對象根據Swing組件的Model,也就是Form對象的資料,修改業務對象的值。為了實現這樣的功能,我也使用了事件機制,實現了這一功能。這將在下文中論述。現在,業務對象和Swing組件之間,通過雙向的事件監聽機制,實現了雙向的引用! 3,在Swing各個組件上註冊響應事件的監聽器(控制器),以響應使用者的操作。這些控制器,使用匿名內部類實現。每一個Swing組件上的控制器,都不僅僅是該Swing組件的控制器,而是整個Swing程式的控制器。因為,內部類可以操縱整個Swing程式的所有資源,因此,我們可以在控制器中,使用所有Swing組件的form,也可以使用所有業務對象,調用所有業務方法,實現任何需要的功能!控制器,是業務功能的進入點,它串連了Swing程式的表現層和業務層,串連了Swing的Form(Swing組件的Model)和業務對象。 現在,我們的Swing程式結構清晰,功能區分合理,低耦合、高內聚,堪稱是MVC模式的典範!
Swing組件和業務對象之間的互動關係在上文中,我們提出了Swing組件和業務對象之間相互的事件監聽機制。Swing組件監聽業務對象,使用“觀察者模式”的一種實現機制,ChangeListener改變監聽器。當然,也可以使用Observe/Observable這樣的機制,或者其它的事件機制。但是,經過權衡,我覺得還是ChangeListener最符合我的需要。它功能強大,又很簡單。當我們需要某個Swing組件監聽我們的業務對象時,我們建立一個該Swing組件的子類,它實現ChangeListener介面,實現public void stateChanged(ChangeEvent e){…}方法,根據監聽的業務對象的資料,構建自己新的Model,從而改變本Swing組件的顯示。 業務對象又該怎樣監聽Swing組件呢?我鐘愛ChangeListener,還是在Swing組件上註冊一個ChangeListener監聽器,這個監聽器就是我們的業務對象。但是,考慮到ChangeListener使用場合甚廣,為了避免Swing組件的其他動作激發該事件,我參照ChangeListener介面,建立了一個類型的新介面:ControllerChangeListener介面。現在,Swing組件上的資料就能夠和我們的業務對象的資料保持同步了!Form和業務對象雖然類型不同,卻好像是同一個對象,有著同樣的資料!
採用MVC模式後的Swing程式的執行流程1,使用者可以看到一個Swing組件構成的GUI介面。2,使用者在介面上進行操作。3,Swing組件的控制器被觸發。1)可能會激發ControllerChangeListener的事件,引起業務對象自動使用Swing組件的Model資料進行更新。2)業務對象更新資料,又會激發業務對象上的ChangeListener的事件。這會引起所有監聽業務對象其Swing組件更新其Model的資料,從而改變Swing組件的顯示。3)我們可能會針對業務對象,執行業務層代碼,進行複雜的業務計算。得到新的業務對象的值。 這同樣會激發業務對象的ChangeListener事件,讓Swing組件的Model得到更新,從而改變Swing組件顯示的介面。4)最後,當然,我們也可以直接修改某些Swing組件的Model或者外觀。因為,作為內部類的控制器可以使用Swing程式所有的屬性和方法。在我的《Swing多線程編程》一文中,我論述過Swing程式中,應該將SwingUI處理代碼和一般的業務代碼分配在不同的線程中。所以,在這裡的控制器中,我們應該使用SwingWorker這個助手類,把業務代碼放在
public Object construct() {…}方法中執行,而把直接修改Swing組件UI的方法,放到
public void finished() {…}方法中執行。這樣,Swing程式的互動性、響應能力和效能將大大提高! 可以看到,這裡,通過將業務對象和Form對象(Swing組件的Model)關聯起來,我們在Swing應用程式中只需要“以業務對象為中心”。操縱業務對象,執行業務操作即可。Swing程式的使用者介面,就會自動更新。這就是採用“以業務對象為中心的MVC模式”的巨大優勢! http://www.cnblogs.com/armlinux/archive/2007/02/05/2391035.html
Swing程式最佳架構設計—以業務對象為中心的MVC模式(轉)