標籤:style class code c java ext
Java是一種物件導向的語言,是實現物件導向編程的強大工具。我們在實際編程中,應該運用並發揮其最大效能。但是,要利用物件導向編程思想,自己獨立開發出好的Java應用程式,特別是大、中型程式,並不是一件簡單的事情。正是基於物件導向編程思想,人們將實際中的各種應用程式,進行了大量的分析、總結,從而歸納出許多標準的設計模式。將這些設計模式合理地運用到自己的實際項目中,可以最大限度地減少開發過程中出現的設計上的問題,確保項目高品質的如期完成。
MVC模式介紹
模型-視圖-控制器(Model-View-Controller,MVC)模式就是為那些需要為同樣的資料提供多個視圖的應用程式而設計的。它很好地實現了資料層與展示層的分離,特別適用於開發與使用者圖形介面有關的應用程式,其見圖1。模式中基本結構定義為:
控制器 用來處理使用者命令以及程式事件的;
模型 維護資料並提供資料存取方法;
視圖 資料的顯示。
MVC模式基本實現過程為:
1. 控制器(如Java中的main程式入口)要建立模型;
2. 控制器要建立一個或多個視圖對象,並將它們與模型相關聯;
3. 控制器改變模型的狀態;
4. 當模型的狀態改變時,模型將會自動重新整理與之相關的視圖。
圖1 MVC模式基本結構
本文要實現的Java應用程式是當使用者在圖形化使用者介面輸入一個球體的半徑時,程式將顯示該球體的體積與表面積。我們首先利用基本MVC模式實現以上程式,然後利用不同數量的模型、視圖、控制器結構來擴充該程式。
基本MVC模式
該程式主要由三個類構成,分別為Sphere類、TextView類及SphereWindow類。其中Sphere類扮演Model的角色,TextView類為View角色,SphereWindow類為Controller角色。
Java通過專門的類Observable及Observer介面來實現MVC編程模式。其UML類圖及MVC模式的實現方式見圖2。
圖2 MVC模式的UML類圖
從圖2中可以看出,Model類必須繼承Observable類,View類必須實現介面Observer。正是由於實現了上述結構,當模型發生改變時(當控制器改變模型的狀態),模型就會自動重新整理與之相關的視圖。其UML順序圖表可以表示為圖3。
Model類Sphere,必須擴充Observable類,因為在Observable類中,方法addObserver()將視圖與模型相關聯,當模型狀態改變時,通過方法notifyObservers()通知視圖。其中實現MVC模式的關鍵代碼為:
import java.util.Observable;class Sphere extends Observable{....public void setRadius(double r) { myRadius = r; setChanged(); // Indicates that the model has changed notifyObservers(); }....} |
圖3 MVC模式的UML順序圖表
View類的角色TextView類必須實現介面Observer,這意味著類TextView必須是implements Observe,另外還需實現其中的方法update()。有了這個方法,當模型Sphere類的狀態發生改變時,與模型相關聯的視圖中的update()方法就會自動被調用,從而實現視圖的自動重新整理。View類的關鍵代碼如下:
import java.util.Observer;import java.util.Observable;public class TextView extends JPanel implements Observer{...... public void update(Observable o, Object arg) { Sphere balloon = (Sphere)o; radiusIn.setText(“ ”+f3.format(balloon.getRadius())); volumeOut.setText(“ ”+f3.format(balloon.volume())); surfAreaOut.setText(“ ” + f3.format(balloon.surfaceArea())); }......} |
SphereWindow類作為Controller,它主要建立Model與View,將view與Model相關聯,並處理事件,其中的關鍵代碼為:
public SphereWindow(){ super(“Spheres: volume and surface area”); model = new Sphere(0, 0, 100); TextView view = new TextView(); model.addObserver(view); view.update(model, null); view.addActionListener(this); Container c = getContentPane(); c.add(view);}public void actionPerformed(ActionEvent e){ JTextField t = (JTextField)e.getSource(); double r = Double.parseDouble(t.getText()); model.setRadius(r);} |
該程式是通過Java中的MVC模式編寫的,具有極其良好的可擴充性。它可以輕鬆實現以下功能:
1. 實現一個模型的多個視圖;
2. 採用多個控制器;
3. 當模型改變時,所有視圖將自動重新整理;
4. 所有的控制器將相互獨立工作。
這就是Java編程模式的好處,只需在以前的程式上稍作修改或增加新的類,即可輕鬆增加許多程式功能。以前開發的許多類可以重用,而程式結構根本不再需要改變,各類之間相互獨立,便於團體開發,提高開發效率。
一個模型、兩個視圖和一個控制器
下面我們討論如何?一個模型、兩個視圖和一個控制器的程式。當使用者在圖形化使用者介面輸入一個球體的半徑,程式除顯示該球體的體積與表面積外,還將圖形化顯示該球體。該程式的4個類之間的可見圖4。
圖4一個模型、兩個視圖和一個控制器的基本結構
其中Model類及View1類根本不需要改變,與前面的完全一樣,這就是物件導向編程的好處。對於Controller中的SphereWindows類,只需要增加另一個視圖,並與Model發生關聯即可。其關鍵實現代碼為:
public SphereWindow() { super(“Spheres: volume and surface area”); model = new Sphere(0, 0, 100); TextView tView = new TextView(); model.addObserver(tView); tView.addActionListener(this); tView.update(model, null); GraphicsView gView = new GraphicsView(); model.addObserver(gView); gView.update(model, null); Container c = getContentPane(); c.setLayout(new GridLayout(1, 2)); c.add(tView); c.add(gView); } |
其程式輸出結果見圖5。
圖5 輸出結果
一個模型、兩個視圖和兩個控制器
在上面的程式中,我們只能通過鍵盤輸進球體半徑,現在我們修改以上程式,利用滑鼠放大、縮小右邊的球體圖形及可改變球體的半徑,從而獲得球體半徑的輸入。
此時的MCV模式為一個模型、兩個視圖和兩個控制器,其結構可以見圖6,其UML類圖可以表示為圖7。
其中Sphere、TextView與GraphicsView類與前面完全一樣。在主程式SphereWindows中,該類這時不是直接作為Controller,它控制Controller1與Controller2的建立。該程式的關鍵代碼為:
public SphereWindow() { super(“Spheres: volume and surface area”); Sphere model = new Sphere(0, 0, 100); TextController tController = new TextController(model); GraphicsController gController = new GraphicsController(model); Container c = getContentPane(); c.setLayout(new GridLayout(1, 2)); c.add(tController.getView()); c.add(gController.getView()); } |
圖6一個模型、兩個視圖和兩個控制器的基本結構
圖7 一個模型、兩個視圖和兩個控制器的UML類圖
當程式SphereWindow運行時,將滑鼠移動到球體的外圓處,點擊拖動即可實現球體的放大與縮小,同時球體半徑、表面積與球體積也同時變化。
小結
從上面介紹可以看出,通過MVC模式實現與圖形使用者化介面相關的應用程式具有極其良好的可擴充性,是Java物件導向編程的未來方向。