一般來說,可以把系統粗略的分為三個層次,視圖層,簡稱為View,它負責數據的輸出和輸入;業務層,簡稱為Model,它代表程序的實際業務;控制層,簡稱為Controller,處理界面的相應并調用業務層進行處理,有時把View和Controller兩層合稱為UI層。
在程序發展的歷史上,MVC模式進過了多次演化,MVC1和MVC2是兩種比較典型的模式,它們的區別主要在于View和Model的聯系方式上。
(1) MVC1模式
這種模式主要用于桌面程序,使用觀察者模式實現,具體來說就是讓View充當觀察者來觀察Model的變化,而用戶交互控制的地方用匿名類的方式統一放在controller中.
View接受用戶輸入,并將交互數據傳遞到Controller.
Controller統一進行處理命令,交由Model處理具體的業務.
進過處理Model更新后,通知View進行更新.
這種模式在舊的桌面應用程序使用較多,但是它的Model必須繼承Observable類,View必須實現Observer接口,人為加大了繼承體系的復雜度;而且Model通知View的方式使View必須了解Model的結構,無謂的加大了兩個類的耦合程度。這些缺點使這種模式逐漸淡出了程序舞臺。


代碼如下:
Control類:
package com.sitinspring;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;


/** *//**
* 控制類
*
* @author sitinspring(junglesong@gmail.com)
*
* @date 2007-11-5
*/

public class Mvc1Ctrl
{
private Mvc1View view;

private Mvc1Model model;


public Mvc1Ctrl()
{
view = new Mvc1View();
model = new Mvc1Model();
model.addObserver(view);
handleEvents();
}

// 處理事件響應

private void handleEvents()
{
addCloseLintener();
addButtonListener();
addButtonListener2();
}

// 窗體關閉事件相應

private void addCloseLintener()
{

view.addWindowListener(new WindowAdapter()
{

public void windowClosing(WindowEvent e)
{
System.out.println("Exit MVC1");
System.exit(0);
}
});
}


private void addButtonListener()
{

view.getButton().addActionListener(new ActionListener()
{

public void actionPerformed(ActionEvent e)
{
model.showText();
}
});
}

private void addButtonListener2()
{

view.getButton2().addActionListener(new ActionListener()
{

public void actionPerformed(ActionEvent e)
{
model.showText2();
}
});
}
}
視圖類(View):
package com.sitinspring;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;


/** *//**
* 視圖類(View)
*
* @author sitinspring(junglesong@gmail.com)
*
* @date 2007-11-5
*/

public class Mvc1View extends JFrame implements Observer
{
private static final long serialVersionUID = 621145935910133202L;

private JButton button;

private JLabel label;

private JButton button2;

private JLabel label2;


public Mvc1View()
{
locateView(300, 200);
this.setTitle("MVC1 Program");
setupComponents();
this.setVisible(true);
}

// 當模塊更新時,此函數會被調用

public void update(Observable o, Object arg)
{
Mvc1Model model = (Mvc1Model) o;


if (model.getUpdateState().equals(Mvc1UpdateState.UpdateLabel))
{
label.setText(model.getResponseText());

} else if (model.getUpdateState().equals(Mvc1UpdateState.UpdateLabel2))
{
label2.setText(model.getResponseText());
}
}

// 定位程序在屏幕正中并設置程序大小

private void locateView(int width, int height)
{
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setSize(width, height);
this.setLocation(screenSize.width / 2 - width / 2, screenSize.height
/ 2 - height / 2);
}

// 初始化內部組件

private void setupComponents()
{
button = new JButton("點擊響應事件1");
label = new JLabel(" 等待事件響應1");

button2 = new JButton("點擊響應事件2");
label2 = new JLabel(" 等待事件響應2");

setLayout(new GridLayout(2, 2));
add(button);
add(label);

add(button2);
add(label2);
}


public JButton getButton()
{
return button;
}


public JButton getButton2()
{
return button2;
}
}
模塊類:
package com.sitinspring;

import java.util.Observable;


/** *//**
* 模塊類
* @author sitinspring(junglesong@gmail.com)
*
* @date 2007-11-5
*/

public class Mvc1Model extends Observable
{
private String responseText;
private String updateState;
// 用于通知View更新,此函數被調用后View的update函數會被調用

private void notifyView()
{
setChanged();
notifyObservers();
}

public void showText()
{
updateState=Mvc1UpdateState.UpdateLabel;
responseText=" 事件1響應完畢";
notifyView();
}

public void showText2()
{
updateState=Mvc1UpdateState.UpdateLabel2;
responseText=" 事件2響應完畢";
notifyView();
}


public String getResponseText()
{
return responseText;
}


public String getUpdateState()
{
return updateState;
}
}
更新狀態輔助類:
package com.sitinspring;


public class Mvc1UpdateState
{
public static final String UpdateLabel="updateLabel";
public static final String UpdateLabel2="updateLabel2";
}
MVC1示例代碼下載:
http://www.tkk7.com/Files/sitinspring/MVC1.rar
(2)MVC2模式
這種模式首見于網絡程序,起初因為Model無法通知到Web程序的界面而發明,這種模式采用Controller做中介者,一方面取得View的輸入,然后交由Model層處理,之后再把返回的數據傳遞到View。
View接受用戶輸入,并傳遞到Controller.
Controller統一進行處理命令,交由Model處理具體的業務.
進過處理Model更新后,Controller會選一個View并把Model內容傳遞(request,session)給它(forward).
然后View進行顯示.
這種模式相對MVC優勢很明顯,首先Model和View無需繼承甚么東西,其次Model和View無需了解對方的存在,只需準備相應的接口而已;缺點是Controller層變得相對復雜了。


代碼如下:
控制類:
package com.sitinspring;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;


/** *//**
* 控制類
*
* @author sitinspring(junglesong@gmail.com)
*
* @date 2007-11-5
*/

public class Mvc2Ctrl
{
private Mvc2View view;

private Mvc2Model model;


public Mvc2Ctrl()
{
view = new Mvc2View();
model = new Mvc2Model();
handleEvents();
}

// 處理事件響應

private void handleEvents()
{
addCloseLintener();
addButtonListener();
addButtonListener2();
}

// 窗體關閉事件相應

private void addCloseLintener()
{

view.addWindowListener(new WindowAdapter()
{

public void windowClosing(WindowEvent e)
{
System.out.println("Exit MVC2");
System.exit(0);
}
});
}


private void addButtonListener()
{

view.getButton().addActionListener(new ActionListener()
{

public void actionPerformed(ActionEvent e)
{
view.getLabel().setText(model.getText());
}
});
}

private void addButtonListener2()
{

view.getButton2().addActionListener(new ActionListener()
{

public void actionPerformed(ActionEvent e)
{
view.getLabel2().setText(model.getText2());
}
});
}
}
視圖類:
package com.sitinspring;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;


/** *//**
* 視圖類(View)
*
* @author sitinspring(junglesong@gmail.com)
*
* @date 2007-11-5
*/

public class Mvc2View extends JFrame
{
private static final long serialVersionUID = 621145935910133202L;

private JButton button;

private JLabel label;

private JButton button2;

private JLabel label2;


public Mvc2View()
{
locateView(300, 200);
this.setTitle("MVC2 Program");
setupComponents();
this.setVisible(true);
}

// 定位程序在屏幕正中并設置程序大小

private void locateView(int width, int height)
{
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setSize(width, height);
this.setLocation(screenSize.width / 2 - width / 2, screenSize.height
/ 2 - height / 2);
}

// 初始化內部組件

private void setupComponents()
{
button = new JButton("點擊響應事件1");
label = new JLabel(" 等待事件響應1");

button2 = new JButton("點擊響應事件2");
label2 = new JLabel(" 等待事件響應2");

setLayout(new GridLayout(2, 2));
add(button);
add(label);

add(button2);
add(label2);
}


public JButton getButton()
{
return button;
}


public JButton getButton2()
{
return button2;
}


public JLabel getLabel()
{
return label;
}


public JLabel getLabel2()
{
return label2;
}
}
模塊類:
package com.sitinspring;


/** *//**
* 模塊類
* @author sitinspring(junglesong@gmail.com)
*
* @date 2007-11-5
*/

public class Mvc2Model
{

public String getText()
{
return " 事件1響應完畢";
}

public String getText2()
{
return " 事件2響應完畢";
}
}
MVC2示例代碼下載:
http://www.tkk7.com/Files/sitinspring/MVC2.rar