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


代碼如下:
Control類(lèi):
package
?com.sitinspring;

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


/**?*/
/**
?*?控制類(lèi)
?*?
?*?
@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();
????}
????
//
?處理事件響應(yīng)
????
private
?
void
?handleEvents()?
{
????????addCloseLintener();
????????addButtonListener();
????????addButtonListener2();
????}
????
//
?窗體關(guān)閉事件相應(yīng)
????
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();
????????????}
????????}
);
????}
}
視圖類(lèi)(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;


/**?*/
/**
?*?視圖類(lèi)(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
);
????}
????
//
?當(dāng)模塊更新時(shí),此函數(shù)會(huì)被調(diào)用
????
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());
????????}
????}
????
//
?定位程序在屏幕正中并設(shè)置程序大小
????
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
);
????}
????
//
?初始化內(nèi)部組件
????
private
?
void
?setupComponents()?
{
????????button?
=
?
new
?JButton(
"
點(diǎn)擊響應(yīng)事件1
"
);
????????label?
=
?
new
?JLabel(
"
??等待事件響應(yīng)1
"
);

????????button2?
=
?
new
?JButton(
"
點(diǎn)擊響應(yīng)事件2
"
);
????????label2?
=
?
new
?JLabel(
"
??等待事件響應(yīng)2
"
);

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

????????add(button2);
????????add(label2);
????}
????
public
?JButton?getButton()?
{
????????
return
?button;
????}
????
public
?JButton?getButton2()?
{
????????
return
?button2;
????}
}
模塊類(lèi):
package
?com.sitinspring;

import
?java.util.Observable;


/**?*/
/**
?*?模塊類(lèi)
?*?
@author
?sitinspring(junglesong@gmail.com)
?*
?*?@date?2007-11-5
?
*/
public
?
class
?Mvc1Model?
extends
?Observable
{
????
private
?String?responseText;
????
private
?String?updateState;
????
????
//
?用于通知View更新,此函數(shù)被調(diào)用后View的update函數(shù)會(huì)被調(diào)用
????
private
?
void
?notifyView()
{
????????setChanged();?????????
????????notifyObservers();
????}
????

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

????
public
?
void
?showText2()
{
????????updateState
=
Mvc1UpdateState.UpdateLabel2;
????????responseText
=
"
??事件2響應(yīng)完畢
"
;
????????notifyView();
????}
????
public
?String?getResponseText()?
{
????????
return
?responseText;
????}
????
public
?String?getUpdateState()?
{
????????
return
?updateState;
????}
}
更新?tīng)顟B(tài)輔助類(lèi):
package
?com.sitinspring;


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


代碼如下:
控制類(lèi):
package
?com.sitinspring;

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


/**?*/
/**
?*?控制類(lèi)
?*?
?*?
@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();
????}
????
//
?處理事件響應(yīng)
????
private
?
void
?handleEvents()?
{
????????addCloseLintener();
????????addButtonListener();
????????addButtonListener2();
????}
????
//
?窗體關(guān)閉事件相應(yīng)
????
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());
????????????}
????????}
);
????}
}
視圖類(lèi):
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;


/**?*//**
?*?視圖類(lèi)(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);
????}

????//?定位程序在屏幕正中并設(shè)置程序大小

????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);
????}

????//?初始化內(nèi)部組件

????private?void?setupComponents()?
{
????????button?=?new?JButton("點(diǎn)擊響應(yīng)事件1");
????????label?=?new?JLabel("??等待事件響應(yīng)1");

????????button2?=?new?JButton("點(diǎn)擊響應(yīng)事件2");
????????label2?=?new?JLabel("??等待事件響應(yīng)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;
????}
}模塊類(lèi):
?
package?com.sitinspring;


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

public?class?Mvc2Model
{

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

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