国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
實(shí)戰(zhàn) PureMVC

實(shí)戰(zhàn) PureMVC


引言

MVC 是一個(gè)非常常見的設(shè)計(jì)模式,被廣泛運(yùn)用于各種和用戶交互的軟件中,像 java Swing 類庫(kù)和 SWT、J2EE 中的 JSP、wxWidgets、QT 和 Gnome 等??梢院懿豢鋸埖恼f(shuō),幾乎所有和 UI 有關(guān)的類庫(kù),不論什么語(yǔ)言,什么平臺(tái)都或多或少有 MVC 的影子。但是經(jīng)過這么多年的發(fā)展,MVC 這個(gè)設(shè)計(jì)模式已經(jīng)由最初 smalltalk 中的樣子發(fā)生了很多變化,除了數(shù)目讓人眼花繚亂外,很多 MVC 模型之間已經(jīng)有了很大差異,不同的人說(shuō)起 MVC 時(shí),除了基本原理外,摻雜了很多平臺(tái)或者語(yǔ)言相關(guān)的東西,經(jīng)常會(huì)引起很多誤解。PureMVC 是一個(gè)跨平臺(tái)跨語(yǔ)言的 MVC 通用框架,這個(gè)框架基于 MVC 模式設(shè)計(jì),清晰簡(jiǎn)單,了解這個(gè)框架會(huì)有助于重新認(rèn)識(shí) MVC 設(shè)計(jì)模式本身,或者能夠提供一個(gè)基礎(chǔ)讓大多數(shù)人能夠更清晰的交流基于 MVC 的設(shè)計(jì)方案。


PureMVC 的簡(jiǎn)介

PureMVC 是在基于模型、視圖和控制器 MVC 模式建立的一個(gè)輕量級(jí)的應(yīng)用框架,這是一個(gè)開源框架,它最初是被用于 ActionScript 3 語(yǔ)言使用的 Adobe Flex、Flash 和 AIR 之上,現(xiàn)在已經(jīng)移植到幾乎所有主要的軟件平臺(tái)之上見表 1。


表 1. PureMVC 支持平臺(tái)語(yǔ)言的一覽表
Language Targets
ActionScript 2 Flex 1.5, Flash 8, FlashLite
ActionScript 3 Flex 2, 3, Flash 9/CS3, AIR.
C# .NET 1.0/2.0 Silverlight, Windows Mobile and Pocket PC.
ColdFusion ColdFusion 8
haXe JavaScript, Flash 8, Flash 9 and the Neko VM.
Java Java Mobile, Standard and Enterprise Editions (ME, SE, EE), JavaFX, Servlets, Applets, and GWT
JavaScript Browser neutral
Objective C Apple iPhone and Mac
PHP PHP 5
Python Python 2.5 for wxPython, Google App Engine, Pyjamas [13]
Ruby
C++ MSVC 8.0/9.0/10.0, MinGW 3.4.5, GNU G++, Embarcadero C++ 6.21

PureMVC 框架有兩個(gè)分支版本:標(biāo)準(zhǔn)和多核。標(biāo)準(zhǔn)版提供了一種簡(jiǎn)單的編碼分離的方法,按照基本的 MVC 概念設(shè)計(jì)而成。多核版本支持模塊化編程,允許多個(gè) PureMVC 應(yīng)用運(yùn)行在一起。本文我們主要介紹標(biāo)準(zhǔn)版的功能和使用。


PureMVC 基本結(jié)構(gòu)

在 MVC 模式中,應(yīng)用程序被分為低耦合的三層:Model、View 和 Controller。PureMVC 在此基礎(chǔ)上有所擴(kuò)充,通過模塊化設(shè)計(jì),致力于進(jìn)一步降低模塊間耦合性,創(chuàng)建了一個(gè)易于擴(kuò)展限制很小的通用框架,圖一是 PureMVC 的設(shè)計(jì)圖。


圖 1. PureMVC 框架示意圖(摘自 PureMVC 官方網(wǎng)站)

(查看圖 1 的 清晰版本。)

在 PureMVC 實(shí)現(xiàn)的經(jīng)典 MVC 元設(shè)計(jì)模式中,Model、View 和 Controller 分別由一個(gè)單例類來(lái)管理,合稱為核心層或核心角色。 另外,在 PureMVC 中還提供了一個(gè)單例類 —— Fa?ade,主要作用是作為與核心層通信的唯一接口,簡(jiǎn)化開發(fā)復(fù)雜度。

從上圖中可以看出,除了這幾個(gè)主要對(duì)象以外,框架還有如下類 Proxy、Mediator 和 Command,以下簡(jiǎn)單介紹一下他們的作用。

  • Proxy 對(duì)象負(fù)責(zé)操作數(shù)據(jù)模型,與遠(yuǎn)程服務(wù)通信存取數(shù)據(jù),這樣可以保證 Model 層的可移植性。通常 Proxy 對(duì)象的引用保存在 Model 中。
  • View 保存對(duì) Mediator 對(duì)象的引用。由 Mediator 對(duì)象來(lái)操作具體的視圖組件(View Component,它的作用還包括:添加事件監(jiān)聽器,發(fā)送或接收 Notification,直接改變視圖組件的狀態(tài)。通過這樣,就可以把視圖和控制它的邏輯分離開來(lái)。
  • Command 對(duì)象是無(wú)狀態(tài)的,只在需要時(shí)才被創(chuàng)建。Command 可以獲取 Proxy 對(duì)象并與之交互,發(fā)送 Notification,執(zhí)行其他的 Command。經(jīng)常用于復(fù)雜的或系統(tǒng)范圍的操作,如應(yīng)用程序的“啟動(dòng)”和“關(guān)閉”。應(yīng)用程序的業(yè)務(wù)邏輯應(yīng)該在這里實(shí)現(xiàn)。

除了基本的對(duì)象結(jié)構(gòu)以外,為了解耦合,PureMVC 框架中引入了事件機(jī)制,這是個(gè)非常簡(jiǎn)單觀察者設(shè)計(jì)模式,所有的事件都是一個(gè) Notification,不同對(duì)象之間通過 Notification 來(lái)同步操作和交換信息。例如如果想更新界面中某個(gè) Mediator,首先我們定義 Notification 用于此目的,然后注冊(cè) Mediator 監(jiān)聽該 Notification,然后就可以在程序中任何地方生成一個(gè) Notification,通過事件機(jī)制,Mediator 就會(huì)接收到 Notification,然后更新需要的部分。整個(gè)過程 Mediator 只和 Notification 有關(guān),沒有其他依賴,有效的降低了對(duì)象之間的依賴程度。

介紹完 PureMVC 的基本結(jié)構(gòu)和事件模型,我們來(lái)看看一個(gè)典型的 PureMVC 應(yīng)用如何構(gòu)造。首先實(shí)際的應(yīng)用程序都有一個(gè) Fa?ade 子類,這個(gè) Fa?ade 類對(duì)象負(fù)責(zé)初始化 Controller(控制器),建立 Command 與 Notification 名之間的映射,并執(zhí)行一個(gè) Command 注冊(cè)所有的 Model 和 View,一旦初始化的工作做完,對(duì)象之間的關(guān)系建立好以后,應(yīng)用程序就可以正常運(yùn)行了。


PureMVC Java 版本的基本結(jié)構(gòu)

首先我們看看 PureMVC Java 標(biāo)準(zhǔn)的核心類圖,如圖 2 所示:


圖 2. Java 版本主類圖

核心類的實(shí)現(xiàn)完全體現(xiàn)了框架的設(shè)計(jì)意圖,由 IController、IView 和 IModel 三個(gè)接口來(lái)規(guī)范 MVC 三種角色的行為,同時(shí)又提供了三個(gè)默認(rèn)的實(shí)現(xiàn)類。

然后我們?cè)诳纯摧o助性類的類圖:


圖 3. Java 版本輔助類圖

(查看圖 3 的 清晰版本。)

從中可以看出 IFa?ade 是整個(gè)程序的入口和負(fù)責(zé)管理所有對(duì)象的類,其中可以注冊(cè) proxy、command 和 Mediator,通過 IFa?ade 的子類,系統(tǒng)的各種資源得到統(tǒng)一管理和調(diào)度。

然后可以看到 INotification 是整個(gè)事件驅(qū)動(dòng)模型的核心類,通過事件模型,整個(gè)應(yīng)用程序的各個(gè)部分的耦合度變得非常低,同時(shí)用戶可以自定義 INotification 的子類,從而實(shí)現(xiàn)最大的可定制性。


PureMVC 樣例程序 —— 用戶登陸

下面我們用 PureMVC 來(lái)實(shí)現(xiàn)一個(gè)典型的應(yīng)用程序通訊錄,這個(gè)程序因?yàn)橹皇鞘痉叮灾粚?shí)現(xiàn)了基本的編輯和管理功能,下圖是程序運(yùn)行時(shí)的截圖。


圖 4. 主界面

當(dāng)用戶填寫正確的用戶名和密碼的時(shí)候,就顯示登陸成功的消息:


圖 5. 登陸成功

當(dāng)用戶填寫錯(cuò)誤的用戶名和密碼的時(shí)候,就顯示登陸不成功的消息:


圖 6. 登陸失敗

首先,我們來(lái)看看程序的入口代碼,即 main 函數(shù)所在的類 LoginFacade,這個(gè)類是 Fa?ade 的子類,同時(shí)繼承了 IFacade 接口。


清單 1. LoginFacade.java 的源碼
				
package login;
import org.puremvc.java.patterns.facade.Facade;
import org.puremvc.java.patterns.observer.Notification;
public class LoginFacade extends Facade {
public static final String STARTUP = "startup";
public static final String SUBMIT_LOGIN = "submitLogin";
public static final String LOGIN_SUCCESSFUL = "loginSuccessful";
public static final String LOGIN_FAIL = "loginFail";
public static LoginFacade getInstance(){
if (instance == null)
instance = new LoginFacade();
return (LoginFacade)instance;
}
protected void initializeController() {
super.initializeController();
registerCommand(STARTUP, StartupCommand.class);
registerCommand(SUBMIT_LOGIN, LoginCommand.class);
}
@Override
protected void initializeModel() {
super.initializeModel();
registerProxy(new UsersProxy());
}
@Override
protected void initializeView() {
super.initializeView();
registerMediator(new LoginScreenMediator());
}
public static void main(String[] args) {
getInstance().notifyObservers(new Notification(STARTUP, null, null));
}
}

LoginFacade 覆蓋父類的三個(gè)初始化方法:initializeController、initializeModel 和 initializeView,作為單例,通過父類的構(gòu)造函數(shù)分別調(diào)用了這三個(gè)函數(shù),從而完成初始化工作。三個(gè)函數(shù)也很簡(jiǎn)單,只是在 initializeController 中注冊(cè)所有的 Command 類,在 initializeModel 中注冊(cè)所有的 Proxy 類,在 initializeView 中注冊(cè)所有 Mediator 類。

Main 函數(shù)很簡(jiǎn)單只是發(fā)送了一個(gè) STARTUP 的消息,該消息會(huì)被 StartupCommand 類接受,從而執(zhí)行相應(yīng)的初始化動(dòng)作。

然后,我們來(lái)看 StartupCommand 類,這個(gè)類很簡(jiǎn)單,在 StartupCommand 中只是設(shè)置了 lookandfeel,然后就調(diào)用系統(tǒng)中已經(jīng)注冊(cè)了的 LoginScreenMediator 類的對(duì)象,然后讓其顯示在桌面上,限于 Swing 的 EDT 特性,所有這些工作都放在 SwingUtilities.invokeLater 中執(zhí)行。

本例中 StartupCommand 沒有執(zhí)行太復(fù)雜的工作,但是實(shí)際運(yùn)行的系統(tǒng),就可以根據(jù)需要在 StartupCommand 中各種需要執(zhí)行的初始化工作。


清單 2. StartupCommand.java 的源碼
				
package login;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import org.puremvc.java.interfaces.INotification;
import org.puremvc.java.patterns.command.SimpleCommand;
public class StartupCommand extends SimpleCommand implements Runnable{
@Override
public void run() {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
LoginScreenMediator mediator = (LoginScreenMediator) this.facade.
retrieveMediator(LoginScreenMediator.NAME);
mediator.show();
} catch (Exception e) {}
}

@Override
public void execute(INotification notification) {
SwingUtilities.invokeLater(this);
}
}

下面我們接著看 LoginScreenMediator 類。


清單 3. LoginScreenMediator.java 的源碼
				
package login;
import java.awt.event.*;
import javax.swing.*;
import org.puremvc.java.interfaces.INotification;
import org.puremvc.java.patterns.mediator.Mediator;
import org.puremvc.java.patterns.observer.Notification;

public class LoginScreenMediator extends Mediator implements ActionListener{
public static final String NAME = "LoginScreenMediator";
private LoginScreen dialog;
public LoginScreenMediator() {
super(NAME, null);
}
public void show(){
dialog = new LoginScreen(new javax.swing.JFrame(), true);
dialog.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
System.exit(0);
}
});
dialog.btnLogin.addActionListener(this);
dialog.setVisible(true);
}
public String[] listNotificationInterests() {
return new String[] { LoginFacade.LOGIN_SUCCESSFUL,
LoginFacade.LOGIN_FAIL };
}
public void handleNotification(INotification note) {
String noteName = note.getName();
if (LoginFacade.LOGIN_SUCCESSFUL.equals(noteName)) {
JOptionPane.showMessageDialog(null, "Login ok!");
System.exit(0);
} else if (LoginFacade.LOGIN_FAIL.equals(noteName)) {
JOptionPane.showMessageDialog(null, "Login failed, try again");
}
}
@Override
public void actionPerformed(ActionEvent e) {
String name = dialog.userName.getText();
String pass = new String(dialog.password.getPassword());
LoginVO userInfo = new LoginVO( name, pass );
this.facade.notifyObservers(new
Notification(LoginFacade.SUBMIT_LOGIN, userInfo, null));
}
}

一般來(lái)說(shuō),Mediator 這個(gè)類負(fù)責(zé)管理視圖,即 Swing 控件或者控件組,同時(shí)響應(yīng)用戶的操作。本例中的 LoginScreenMediator 管理了 LoginScreen 這個(gè) Swing 控件。LoginScreenMediator 的 show 函數(shù)的工作首先初始化 LoginScreen,LoginScreen 就是我們顯示給用戶看的 JDialog 子類,其中有兩個(gè) JLabel,一個(gè) JText Field,一個(gè) JPassword Field 和一個(gè)按鈕,這里就不列出 LoginScreen 的代碼,可以在附件中的源碼查看詳細(xì)代碼。

LoginScreenMediator 的 show 函數(shù)然后注冊(cè)了 Login 按鈕的 ActionEvent 事件,然后就顯示了 LoginScreen 控件。到此為止,用戶界面的顯示工作就完成了。LoginScreenMediator 類中另外一個(gè)需要注意的地方是 listNotificationInterests,在這個(gè)方法中該類說(shuō)明了它所關(guān)注的 Notification:LOGIN_SUCCESSFUL 和 LOGIN_FAIL。以后一旦有出現(xiàn)了這兩個(gè) Notification,LoginScreenMediator 類的 handleNotification 函數(shù)就會(huì)被調(diào)用。

下面我們來(lái)看用戶事件處理部分,界面顯示之后,一旦用戶點(diǎn)擊填入用戶名和密碼,然后點(diǎn)擊 Login 按鈕,就會(huì)觸發(fā) LoginScreenMediator 的 public void actionPerformed(ActionEvent e) 函數(shù),在這個(gè)函數(shù)中只是獲取用戶名和密碼,然后把得到的信息,通過 SUBMIT_LOGIN 這個(gè) Notification 發(fā)送出去,因?yàn)楸绢惖墓ぷ髦皇秦?fù)責(zé)管理 View,具體如何驗(yàn)證登陸信息則不是它關(guān)注的范圍,自然有其他 Command 處理。

在前面的 LoginFacade 中注冊(cè)了一個(gè) LoginCommand 類來(lái)處理 SUBMIT_LOGIN 這種類型的 Notification,下面是 LoginCommand 的源碼。


清單 4. LoginCommand.java 的源碼
				
package login;
import org.puremvc.java.interfaces.INotification;
import org.puremvc.java.patterns.command.SimpleCommand;
public class LoginCommand extends SimpleCommand {
@Override
public void execute(INotification notification) {
UsersProxy usersProxy = (UsersProxy)
his.facade.retrieveProxy(UsersProxy.NAME);
LoginVO userInfo = (LoginVO) notification.getBody();
if(usersProxy.checkLogin(userInfo)){
sendNotification(LoginFacade.LOGIN_SUCCESSFUL, null, null);
} else {
sendNotification(LoginFacade.LOGIN_FAIL, null, null);
}
}
}

LoginCommand 接收到 Notification 之后,首先獲取其中的附加信息(用戶名和密碼),然后通過系統(tǒng)中已經(jīng)注冊(cè)的 UsersProxy 來(lái)檢查用戶名和密碼是否,如果正確,就發(fā)送 LOGIN_SUCCESSFUL 的 Notification,否則就發(fā)送 LOGIN_FAIL 的 Notification。本例中 UsersProxy 的功能非常簡(jiǎn)單,只是檢查一個(gè)內(nèi)存中 map,看看接收的用戶名和密碼,是否和已經(jīng)保存在 map 中預(yù)設(shè)值數(shù)據(jù)是否一致,實(shí)際上,這里也可以通過檢查 LDAP 或者數(shù)據(jù)庫(kù)之類的 UserStore 來(lái)執(zhí)行,效果是類似的。

下面我們看 LOGIN_SUCCESSFUL 和 LOGIN_FAIL 的 Notification 的處理,前面提到 LoginScreenMediator 類關(guān)注這兩個(gè) Notification,所以它會(huì)在 handleNotification 函數(shù)中處理這兩個(gè) Notification,限于示例,程序的功能就只是給用戶提示一個(gè)登陸成功或失敗的消息。

以上就是演示代碼的所有功能,從基本的代碼結(jié)構(gòu)來(lái)看,類比較多,但是大家可以看到每個(gè)類都很簡(jiǎn)單,職責(zé)也很清楚,同時(shí)每個(gè) Command、Proxy 和 Mediator 類之間的耦合度很小,Mediator 和 Proxy 甚至都不知道對(duì)方的存在,也依賴 Command 類,這樣一來(lái),Proxy 和 Mediator 的復(fù)用程度變高了。

另外 Notification 機(jī)制,大家可以看到程序有很強(qiáng)的類似工作流的性質(zhì),其實(shí)在實(shí)際使用過程中,完全可以根據(jù)需求分析的結(jié)果,結(jié)合工作流來(lái)定義 Notification。 Notification 和 Swing 事件不一樣,它不關(guān)注于用戶的鍵盤等 UI 事件,它關(guān)注業(yè)務(wù)流程,所以也是一個(gè)非常有力幫助需求人員和設(shè)計(jì)人員之間的溝通。


總結(jié)

PureMVC 框架作為一個(gè)成熟的通用框架,具有以下優(yōu)點(diǎn):

  • 輕量級(jí)的庫(kù),簡(jiǎn)潔適度的設(shè)計(jì)
  • 極大的降低耦合度
  • 大量的文檔和成熟的應(yīng)用范例
  • 平臺(tái)語(yǔ)言無(wú)關(guān)
  • 減少?gòu)?fù)雜度,讓熟悉 MVC 概念的設(shè)計(jì)人員之間溝通更容易
  • 代碼簡(jiǎn)潔,簡(jiǎn)單易學(xué)
  • 不依賴任何第三方的庫(kù)

從上面的介紹中,我們可以看到,在一個(gè)項(xiàng)目中根據(jù)實(shí)際情況整合 PureMVC 框架,可以讓可以使得和 UI(不限于 Swing)相關(guān)部分設(shè)計(jì)更簡(jiǎn)潔,并提供更多的可復(fù)用組件,增強(qiáng)需求和設(shè)計(jì)之間的溝通效果,有效提高項(xiàng)目的設(shè)計(jì)質(zhì)量。



下載

描述名字大小下載方法
本文樣例代碼Login.zip6 KBHTTP

關(guān)于下載方法的信息


參考資料

學(xué)習(xí)

討論

關(guān)于作者

任偉博,擅長(zhǎng)的技術(shù)領(lǐng)域包括 J2EE、系統(tǒng)構(gòu)架、設(shè)計(jì)/分析模式、數(shù)據(jù)挖掘。



(###)
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
flex框架pureMVC的使用:第一步
PureMVC的十個(gè)小提示 - 百草園 - JavaEye技術(shù)網(wǎng)站
串講23種設(shè)計(jì)模式
(四十二)Context.startForegroundService() did not then call Service.startForeground?
從MVC框架看MVC架構(gòu)的設(shè)計(jì)
Java23種設(shè)計(jì)模式匯總篇
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服