GWT MVP變得簡單

GWT Model-View-Presenter是用于大規模應用程序開發的設計模式。 它源于MVC,它在視圖和邏輯之間進行劃分,并有助于創建結構良好,易于測試的代碼。 為了幫助像我這樣的懶惰開發人員,我研究了如何減少使用聲明式UI時要編寫的類和接口的數量。

經典MVP

您知道如何在Facebook中發布鏈接嗎? –最近,我不得不為一個小GWT旅行應用程序創建此功能。

因此,您可以輸入一個URL,然后將其提取并解析。 您可以從頁面中選擇圖像之一,查看文本,最后存儲鏈接。
現在如何在MVP中正確設置此設置? –首先,創建一個類似于視圖的抽象接口:

interface Display {HasValue<String> getUrl();void showResult();HasValue<String> getName();HasClickHandlers getPrevImage();HasClickHandlers getNextImage();void setImageUrl(String url);HasHTML getText();HasClickHandlers getSave();
}

它利用GWT組件實現的接口來提供對其狀態和功能的某些訪問。 在測試期間,您無需參考GWT內部即可輕松實現此接口。 同樣,可以在不影響更深層邏輯的情況下更改視圖實現。
該實現非常簡單,此處顯示了聲明的UI字段:

class LinkView implements Display@UiField TextBox url;@UiField Label name;@UiField VerticalPanel result;@UiField Anchor prevImage;@UiField Anchor nextImage;@UiField Image image;@UiField HTML text;@UiField Button save;public HasValue<String> getUrl() {return url;}public void showResult() {result.setVisible(true);}// ... and so on ...
}

然后,演示者使用接口訪問視圖,按照慣例,該接口寫在presenter類中:

class LinkPresenterinterface Display {...};public LinkPresenter(final Display display) {display.getUrl().addValueChangeHandler(new ValueChangeHandler<String>() {@Overridepublic void onValueChange(ValueChangeEvent<String> event) {Page page = parseLink(display.getUrl().getValue());display.getName().setValue(page.getTitle());// ...display.showResult();}});}// ... and so on ...
}

因此,我們在這里:使用MVP,您可以很好地構造代碼并使代碼易于閱讀。

簡化

收益是: 每個屏幕或組件三種類型 。 每當重新定義UI時,三個文件都將更改。 未將ui.xml文件計入視圖聲明。 對于像我這樣的懶人來說,這些太多了。 而且,如果您查看視圖實現,很明顯如何簡化它:
使用視圖聲明(* .ui.xml)作為視圖,并將ui元素直接注入到presenter中:

class LinkPresenter@UiField HasValue<String> url;@UiField HasValue<String> name;@UiField VerticalPanel result;@UiField HasClickHandlers prevImage;@UiField HasClickHandlers nextImage;@UiField HasUrl image;@UiField HasHTML text;@UiField HasClickHandlers save;public LinkPresenter(final Display display) {url.addValueChangeHandler(new ValueChangeHandler<String>() {@Overridepublic void onValueChange(ValueChangeEvent<String> event) {Page page = parseLink(url.getValue());name.setValue(page.getTitle());// ...result.setVisible(true);}});}// ... and so on ...
}

由于可以使用它們的接口聲明注入的元素,因此此演示者具有成熟的MVP演示者的許多優點:您可以通過設置實現組件來對其進行測試(請參見下文),并且可以輕松地更改視圖實現。
但是現在,您將所有這些都放在一個類和一個view.ui.xml文件中,并且可以更簡單地應用結構更改。

使UI元素抽象

TextBox實現HasValue <String>。 這很簡單。 但是,不能通過接口訪問的ui元素的屬性呢? 您可能已經認識到的一個示例是上述代碼中的VerticalPanel命名結果result及其方法setVisible(),不幸的是,該方法在UiObject基類中實現。 因此,沒有可用的接口,例如。 在測試時實施。 為了能夠切換視圖實現,最好注入ComplexPanel,但即使在測試時也無法實例化。

例如,在這種情況下,唯一的解決方法是創建一個新接口

interface Visible {void setVisible(boolean visible);boolean isVisible();
}

和子類化有趣的UI組件,實現相關的接口:

package de.joergviola.gwt.tools;
class VisibleVerticalPanel extends VerticalPanel implements Visible {}

這似乎是乏味和次優的。 但是,只能像上述成熟的MVP中那樣僅針對每個組件而不是針對每個視圖進行操作。
等待-如何在UiBuilder模板中使用自制組件? –很簡單:

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:t="urn:import:de.joergviola.gwt.tools"><g:VerticalPanel width="100%"><g:TextBox styleName="big" ui:field="url" width="90%"/><t:VisibleVerticalPanel ui:field="result"visible="false"  width="100%"></t:VisibleVerticalPanel></g:VerticalPanel>
</ui:UiBinder>

聲明處理程序

聲明(click-)處理程序的標準方法非常方便:

@UiHandler("login")public void login(ClickEvent event) {srv.login(username.getValue(), password.getValue());}

在簡化的MVP方法中,此代碼將駐留在演示者中。 但是ClickEvent參數是View組件,可以例如。 不能在運行時實例化。 另一方面,由于UiBuilder需要Event參數,因此無法從簽名中將其刪除。

因此,不幸的是,您必須堅持手動注冊ClickHandlers(因為無論如何都必須執行完整的MVP):

public initWidget() {...login.addClickHandler(new ClickHandler() {@Overridepublic void onClick(ClickEvent event) {login();}});...
}public void login(ClickEvent event) {srv.login(username.getValue(), password.getValue());
}

測試中
引入MVP時,使您的應用程序可測試是主要目標之一。
GwtTestCase能夠在容器環境中執行測試,但需要一些啟動時間。 在TDD中,希望有一個運行速度非常快的測試,可以在每次更改后應用它而不會丟失上下文。 因此,MVP旨在能夠在標準JVM中測試所有代碼。 在標準MVP中,您將創建視圖接口的實現。 在這種簡化方法中,只需在組件接口級別上創建實現即可,如下所示:

class Value<T> implements HasValue<T> {private T value;List<ValueChangeHandler<T>> handlers = new ArrayList<ValueChangeHandler<T>>();@Overridepublic HandlerRegistration addValueChangeHandler(ValueChangeHandler<T> handler) {handlers.add(handler);return null;}@Overridepublic void fireEvent(GwtEvent<?> event) {for (ValueChangeHandler<T> handler : handlers) {handler.onValueChange((ValueChangeEvent) event);}}@Overridepublic T getValue() {return value;}@Overridepublic void setValue(T value) {this.value = value;}@Overridepublic void setValue(T value, boolean fireEvents) {if (fireEvents)ValueChangeEvent.fire(this, value);setValue(value);}}

與往常一樣,您必須將此組件注入到被測演示者中。 盡管從原則上講,您可以為組件創建一個設置器,但我仍然遵循通常的技巧來使組件受到包保護,將測試與演示者放入同一包中(但當然是不同的項目文件夾),然后直接設置組件。

你贏了什么?

您得到的代碼結構像完整的MVP一樣干凈,只需要更少的類和樣板代碼。
在某些情況下,組件及其接口需要實用程序類,但是隨著時間的流逝,您將構建一個真正易于理解,測試和擴展的環境。

我很好奇:告訴我您的經歷!

參考: GWT MVP從我們的JCG合作伙伴那里變得簡單 ? Joerg Viola在Joerg Viola博客上 。


翻譯自: https://www.javacodegeeks.com/2012/02/gwt-mvp-made-simple.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373263.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373263.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373263.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php如何編寫通信協議,定制通訊協議

## 如何定制協議實際上制定自己的協議是比較簡單的事情。簡單的協議一般包含兩部分:* 區分數據邊界的標識* 數據格式定義## 一個例子### 協議定義這里假設區分數據邊界的標識為換行符"\n"(注意請求數據本身內部不能包含換行符)&#xff0c;數據格式為Json&#xff0c…

今年計劃要看的書全部備齊

上個月購買的書《今年計劃看的書其中幾本》 http://www.cnblogs.com/insus/p/5325513.html 昨天購買的書回來了&#xff0c;今年計劃要看的書全部備齊。《MongoDB》&#xff0c;《深入理解Bootstarp》和《ASP.NETSignalR編程實踐》…… 轉載于:https://www.cnblogs.com/in…

Codevs 2756 樹上的路徑

2756 樹上的路徑 時間限制: 3 s    空間限制: 128000 KB    題目等級 : 大師 Master題目描述 Description給出一棵樹&#xff0c;求出最小的k&#xff0c;使得&#xff0c;且在樹中存在路徑P&#xff0c;使得k> S 且 k <E. &#xff08;k為路徑P上的邊的權值和&a…

圖形教程

眾所周知&#xff0c;我們可以借助Java庫制作游戲&#xff0c;這些庫為我們提供制作游戲所需的圖形。 因此&#xff0c;今天我將開始一個關于Java圖形的非常新的部分。 我之前曾發表過有關如何制作所得稅計算器的文章 。 首先要滿足一些先決條件&#xff1a; -您應該對Java語法…

文件上傳預覽

<fieldset><legend>使用readAsDataUrl()方法預覽圖片</legend><input type"file" name"fileUpload" id"fileUpload" onchange"filePrevImg(this.files);" multiple"true" /><ul id"prevUpl…

c++強制類型轉換:dynamic_cast、const_cast 、static_cast、reinterpret_cast

一、介紹 dynamic_cast: 通常在基類和派生類之間轉換時使用const_cast: 主要針對const和volatile的轉換static_cast: 一般的轉換(no run-time check)通常&#xff0c;如果你不知道該用哪個&#xff0c;就用這個。 reinterpret_cast: 用于進行沒有任何關聯之間的轉換&…

K8S Pod Terminating/Unknown故障排查

一、pod異常出現現象 優雅終止周期(Graceful termination period): 當pod被刪除時&#xff0c;會進入"Terminating"狀態&#xff0c;等待容器優雅關閉。如果容器關閉所需時間超過默認期限(默認30秒)&#xff0c;則pod將保持在"Terminating"狀態。 Finalize…

矩陣指數 matlab,矩陣指數 - MATLAB Simulink Example - MathWorks 中國

方法 1&#xff1a;加權平方expmdemo1 是以下著作中算法 11.3.1 的實現&#xff1a;Golub, Gene H. and Charles Van Loan.Matrix Computations, 3rd edition.Baltimore, MD:Johns Hopkins University Press, 1996.% Scale A by power of 2 so that its norm is < 1/2 .[f,e…

向導設計模式

我們都喜歡巫師……。 &#xff08;我的意思是軟件向導&#xff09;。 我們總是很高興跳上那些“下一步”按鈕&#xff0c;就像我們在我們的時髦的小雞上跳舞一樣。 因此&#xff0c;今天我們將您心愛的向導帶入您的編碼經驗中。 讓我們跳入一個例子。 假設您要設計一個Conserv…

IO(三)字節流練習

public class ByteStreamDemo {/*int available(); 可以取得輸入文件的大小&#xff08;字節個數&#xff09;,沒有返回0void close(); 關閉輸入流abstract int read(); 讀取一個字節&#xff0c;并把讀…

基于matlab的人臉五官邊緣檢測方法,人臉邊緣檢測方法研究與仿真

人臉表情是人類情感的主載體之一,它含有豐富的人體行為信息。通過臉部表情能夠表達人微妙的情緒反應以及對應的心理狀態[1],人臉表情識別技術隨著人們對表情信息的日益重視而受到關注,現已成為人們研究的熱點。基于幾何特征提取是一個快速、直接、有效的人臉表情識別方法,運用基…

GWT –利弊

我喜歡JavaScript。 隨著jQuery和Mootools的出現&#xff0c;我對JavaScript的熱愛僅增加了很多倍。 只要有選擇&#xff0c;我就可以將上述框架中的任何一個用于我開發的任何Web應用程序。 但是進入服務行業后&#xff0c;我不得不一次次屈服于客戶的壓力&#xff0c;并在他們…

秦九韶算法matlab實驗報告,數值分析上機實驗報告.doc

實驗報告一題目&#xff1a; (緒論) 非線性方程求解及誤差估計摘要&#xff1a;非線性方程的解析解通常很難給出&#xff0c;因此線性方程的數值解法就尤為重要。本實驗采用兩種常見的求解方法二分法、Newton法和改進的Newton法。可以節省計算機的計算時間&#xff0c;還能減小…

Flex 布局教程:語法篇

網頁布局&#xff08;layout&#xff09;是CSS的一個重點應用。 布局的傳統解決方案&#xff0c;基于盒狀模型&#xff0c;依賴 display屬性 position屬性 float屬性。它對于那些特殊布局非常不方便&#xff0c;比如&#xff0c;垂直居中就不容易實現。 2009年&#xff0c;W3…

練習錯誤

form:阻止表單提交的方法一&#xff1a;在form標簽中給出以下代碼&#xff1a; 1 onsubmit "return False" 方法二&#xff1a;設置事件阻止 1 e.preventDefault() js中判斷&#xff1a;只要非數字都應該表示為字符串 1 if(Email.indexOf("") -1){ 2 …

JavaFX 2中的PopupMenu

創建彈出菜單 要在JavaFX中創建Popupmenu&#xff0c;可以使用ContextMenu類。 您向其中添加MenuItems&#xff0c;也可以使用SeparatorMenuItem創建可視分隔符。 在下面的示例中&#xff0c;我選擇子類ContextMenu并將MenuItems添加到其構造函數中。 public class Animatio…

matlab中CH指標聚類評價指標,MATLAB聚類有效性評價指標(外部)

MATLAB聚類有效性評價指標(外部)作者&#xff1a;凱魯嘎吉 - 博客園 http://www.cnblogs.com/kailugaji/更多內容&#xff0c;請看標簽&#xff1a;MATLAB、聚類前提&#xff1a;數據的真實標簽已知&#xff01;1. 歸一化互信息(Normalized Mutual information)定義程序functio…

學習進度表

周數 專業學習目標 專業學習時/每分鐘 新增代碼量 知識技能總結 第六周 ps的圖像處理 80 30 看書加以實踐 第七周 數據結構的鏈式結構 100 50 多做習題加以鞏固知識 第八周 網頁設計 80 30 多多練習&#xff0c;學會用代碼設計 第九周 圖片美工 70 30 慢慢學會運用軟…

Axis通過wsdd部署Web Service

axis網上的教程很多&#xff0c;不過搜來搜去&#xff0c;總是只有那么幾篇。仔細看了一下那幾篇文章&#xff0c;都感覺到不是自己想要的&#xff0c;所以自己整理了一篇分享一下。 本文介紹axis應用的一個小例子&#xff0c;沒有麻煩的命令行操作&#xff0c;只需照下面的步驟…

彈簧特性

1.概述 本教程將展示如何通過XML或Java配置在Spring中設置和使用屬性 。 在Spring 3.1之前 &#xff0c;將新的屬性文件添加到Spring并使用屬性值并不像它那樣靈活和健壯。 從Spring 3.1開始 &#xff0c;新的Environment和PropertySource抽象大大簡化了此過程。 2.通過XML名…