亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

采用敏捷方法進行用戶界面開發

2019-11-18 12:16:22
字體:
來源:轉載
供稿:網友

  摘要
  
  1991年秋,在美國勒海大學亞科卡學院的一份研究報告《21世紀美國制造業的戰略:一個工業主導的觀點》中,首次提出了靈敏競爭的概念.而今天,我們似乎已經看到,靈敏已經在我們身邊,形影不離.
  
  之前Matrix一則討論激烈的新聞(http://www.matrix.org.cn/resource/news/314_Agile.Html), 也表達了靈敏在今天的熱度.下面通過一個簡單的例子, 告訴你如何起步靈敏開發..
  
  概述
  
  假如你沒有采用靈敏的方式,那你就落后了。這是最近SD Best PRactices 2004會議上的標語。靈敏的方法就象XP和Scrum正在世界的軟件發展中,變得越來越普遍了。靈敏是一個巨大的改變,讓軟件開發者把重心轉移到質量和速度上。這對已經被比喻成面向對象設計的軟件開發有很大的影響。但是,這種影響的一些方面已經放慢了:GUI的開發,自從大多數軟件包含了一些類型的GUI,而且比較多的軟件開發的百分比是去完成以GUI為中心的,應用靈敏的優勢去開發GUI就是要害問題了。
  
  什么在阻止人們用靈敏的方法來開發GUI呢?不論他們的應用是基于web的或是桌面應用,大多數開發者不做用戶界面user interface的測試驅動開發test-driven development (TDD)。這都因為一個簡單的原因:單元測試GUI是很困難的。測試GUI是很乏味沉悶而且輕易出錯的,包含了模擬用戶事件的復雜代碼,在事件傳播和控制重繪的時候等待,然后在他顯示給用戶之前,嘗試著檢測狀態。靈敏依靠于測試驅動開發,但是為GUI的特定行為來寫有效的測試代碼是困難的。在cube farm(辦公農莊,用隔斷間隔成很多小工作間的辦公室? 商務英語)的GUI方面上,質量和設計從靈敏方法中受益已經被完全熟悉到。
  
  靈敏實踐正在滲透進這個領域。單元測試GUI元素的工具激增,JFCUnit 框架測試GUI是用java Swing,基于Web的GUI能被HTMLUnit, HTTPUnit, jWebUnit和類似的工具測試。許多GUI構造器和工具包和單元測試工具有關系,比如VBUnit是為了Visual Basic,QtUnit是給Qt用的。
  
  工具已經存在了,但是處理仍是不確定的。在測試驅動開發(TDD)中,每個代碼的改變都在新行為的單元測試前。在開發GUI時,許多變化不過是視覺顯示上的調整,比如改變元素的位置,文本,或者顏色。你可以加一個按鈕,建一個菜單項,或者構造一個對話框。但是怎樣和為什么你要測試這種變化呢?測試每個標簽或者顏色值是很愚蠢的。同樣的,對于標準的元素象按鈕和域,測試他們通常的行為是沒有意義的,象對鼠標移動的響應,鍵的按下,點擊,和諸如此類的。這些事情是不可能被中斷的。怎樣去測試他們的問題只是徒勞的增添了做GUI測試的難度。
  
  一個要害的問題:怎樣做測試先行的開發?答案就在于GUI的編碼是怎樣組織的。靈敏方式的領袖例如Kent Beck 和 David Astels建議在構造GUI的時候要保持視圖對象盡可能是輕量的,而且“在表面下”( below the surface.)測試視圖層。這個 靈敏對象/瘦視圖 模型和我們熟悉的 文檔-視圖 及 客戶端-服務器模式類似,但是被應用于個別的GUI元素。內容和表現的分離改善了代碼的設計,使他更模塊化和更利于測試。每個用戶界面的組件被實現為一個靈敏對象,包括將要被測試的應用的行為,但不包括GUI表現的代碼。每個靈敏對象有一個相應的瘦視圖類只包括普通的GUI行為。采用這種設計模式,GUI構造變得可以被應用于 測試驅動開發(TDD) 處理了。
  
  例子:構造一個登錄對話框
  
  讓我們進入一個例子看看怎樣使用TDD和 靈敏對象/瘦視圖 代碼設計模式去開發一個GUI對話框。起初,讓我們考慮對話框的圖形,靈敏開發提倡預先最小化設計,讓軟件構架在多次循環開發中重構,但是這個方法對GUI設計不是很合適。設計一個用戶界面是一個創造的過程,應該規范地處理,畫草圖,做原型,和可用性測試。然后,盡管在GUI下的代碼可以用TDD迭代地設計,一個形象的設計草圖是明智的第一步。這個對話框的基本的設計在圖1中勾畫出來。
  
  
 采用靈敏方法進行用戶界面開發(圖一)
  Figure 1. GUI design sketch for login dialog

  
  這個對話框很簡單,包括用戶名和密碼域,相應的靜態文本框和標簽,登錄和取消按鈕。做為一個他行為的初始輪廓,我們決定登錄成功的話對話框關閉,登錄失敗的話對話框仍然開著。取消按鈕也關閉對話框。
  
  基本的 靈敏對象/瘦視圖 代碼類設計的對話框實現在圖2中表示。
  
  
 采用靈敏方法進行用戶界面開發(圖二)
  Figure 2. The classes LoginDialog and LoginDialogView

  
  靈敏對象類LoginDialog 將包含一個方法對應對話框的每個功能行為。瘦視圖類LoginDialogView 將只包含簡單的和顯示相關的代碼,還有get/set 方法去讀取和設置顯示的信息。在這個過程里,只有LoginDialog里復雜的功能需要被單元測試。我們可以十分自信在LoginDialogView 里的簡單行為可以正常工作。
  
  第一個構造的組件是靈敏對象LoginDialog 。他需要一個相應的測試類LoginDialogTest 。第一個測試方法將要驗證登錄方法,如圖3所示。
  
  
 采用靈敏方法進行用戶界面開發(圖三)
  Figure 3. The smart object LoginDialog and its test class LoginDialogTest
  

  作為測試先行的開發方法規定,首先要寫單元測試。測試預期和定義了要被測試的功能設計。我們需要獲得一個用戶名和密碼,然后返回一個登錄成功或者登錄失敗。一個用來判定的接口方法來做剛才所述的
  
  boolean login(String username, String passWord);
  
  測試類LoginDialogTest 將測試這個功能。例1展示了在LoginDialogTest.java. 文件中他的初始實現。
  
  LoginDialogTest.java
  
  import junit.framework.*;
  public class LoginDialogTest extends TestCase {
  public void testLogin() {
  LoginDialog dialog = new LoginDialog();
  assertTrue( dialog.login("user", "passwd") );
  }}
  
  這個測試是基于JUnit基礎測試類TestCase的。測試方法testLogin()創建了一個LoginDialog 的實例,調用了他的login()方法,然后判定結果是真。這段代碼將不會編譯,因為LoginDialog 不存在。在TDD過程后,LoginDialog
  
  將生成和保存,代碼編譯后,測試運行驗證將象預期的那樣失?。ㄒ驗榉椒]有實現)。然后 LoginDialog 為了通過單元測試給出最小的實現,遵照靈敏的圣條 做 可能工作的最簡單的事情(the simplest thing that could possibly work)。例2展示了最初的LoginDialog 版本,用最少的代碼通過了單元測試,實現在LoginDialog.java. 文件里。
  
  LoginDialog.java
  
  public class LoginDialog {
  LoginDialog() {}
  public boolean login(String username, String password) {
  return true;  } }
  
  使用下面的命令來運行代碼
  javac -classpath ".;junit.jar" LoginDialogTest.java
  javac -classpath "." LoginDialog.java
  
  classpath 必須包括junit.jar 來運行單元測試,因為他使用了JUnit.在linux,Mac OSX,還有其他的UNIX系統上,classpath將包含一個冒號(:)而不是想下面那樣用一個分號。
  
  測試將如下運行
  
  java -classpath ".;junit.jar" junit.textui.TestRunner LoginDialogTest
  
  單元測試通過了,真好!不幸的是,這個編碼只是模擬一下。Login()方法將總是批準登錄。毋庸置疑,客戶將不會欣賞這種水平的安全機制。顯然,要寫的下一個測試是驗證假如給的條件不正確的話將失敗。例3展示了LoginDialogTest 的第二個測試方法去實現這個目的,testLoginFail() 。既然兩個測試都使用一個LoginDialog 的實例,測試類被重構為在他的setUp() 方法里創建一個固定的測試用的LoginDialog。
  
  LoginDialogTest.java
  
  import junit.framework.*;
  public class LoginDialogTest extends TestCase {
  private LoginDialog dialog;
  public void setUp() {
  dialog = new LoginDialog();
  }
  public void testLogin() {
  assertTrue( dialog.login("user", "passwd") );
  }
  public void testLoginFail() {
  assertFalse( dialog.login("", "") );
  }}
  
  LoginDialog 必須得通過新的測試,不能在第一次測試的時候有失敗。TDD過程引導我們構造我們需要的真正的功能,在用正確的用戶名和密碼登錄的時候,能成功登錄,假如不是,就失敗。例4展示了按此修改的LoginDialog
  
  LoginDialog.java
  
  public class LoginDialog {
  private String user = "user";
  private String passwd = "passwd";
  LoginDialog() {}
  public boolean login(String username, String password) {
  if (user.equals(username) && passwd.equals(password))
  return true;
  else
  return false;
  } }
  
  LoginDialog 現在能通過所有的測試。為此,他包括了符合成功登錄條件的用戶名和密碼域。顯然,這只是比第一個版本的安全性能稍微好一些。登錄代碼不應該包含認證的硬編碼!基于這點,我們應該引入一個單獨的類來包含LoginDialog 用的驗證用戶的登錄信息。然而,這個例子是關于GUI構造的,那讓我們暫停這個不安全的登錄代碼,繼續GUI方面。
  
  現在,我們已經建立了登錄功能,并用單元測試覆蓋了他,但沒有可視的GUI來顯示它。那下一步該做什么呢?對于已經作的和測試的實際功能,在GUI方面做的是創建和顯示圖像元素,然后在適當的時候調用login()方法。這個功能是普通和輕易建立的,所以他不包含能中斷和需要單元測試的復雜行為。因此,當建立GUI元素時,我們不需要去做測試先行的開發。例5展示了創建對話框窗口的Swing類LoginDialogView ,他的實現在LoginDialogView.java.文件。
  
  LoginDialogView.java
  
  import java.awt.*;
  import java.awt.event.*;
  import javax.swing.*;
  public class LoginDialogView extends JFrame
  implements ActionListener {
  protected JTextField usernameField;
  protected JTextField passwordField;
  protected JButton loginButton;
  protected JButton cancelButton;
  private LoginDialog dialog;
  LoginDialogView(LoginDialog dlg) {
  super("Login");
  setSize(300, 140);
  dialog = dlg;
  addControls();
  loginButton.addActionListener( this );
  cancelButton.addActionListener( this );
  }
  public void actionPerformed(ActionEvent e) {
  String cmd = e.getActionCommand();
  if (cmd.equals("Login")
  && dialog.login(usernameField.getText(),
  passwordField.getText())) {
  hide();
  }
  }
  private void addControls() {
  Container contentPane = this.getContentPane();
  contentPane.setLayout(new GridBagLayout());
  GridBagConstraints c = new GridBagConstraints();
  JLabel label1 = new JLabel("Username:", Label.RIGHT);
  c.insets = new Insets(2, 2, 2, 2);
  c.gridx = 0;
  c.gridy = 0;
  contentPane.add(label1, c);
  usernameField = new JTextField("", 60);
  usernameField.setMinimumSize(new Dimension(180, 30));
  c.gridx = 1;
  contentPane.add(usernameField, c);
  JLabel label2 = new JLabel("Password:", Label.RIGHT);
  c.gridx = 0;
  c.gridy = 1;
  contentPane.add(label2, c);
  passwordField = new JTextField("", 60);
  passwordField.setMinimumSize(new Dimension(180, 30));
  c.gridx = 1;
  contentPane.add(passwordField, c);
  loginButton = new JButton("Login");
  c.gridx = 0;
  c.gridy = 2;
  contentPane.add(loginButton, c);
  cancelButton = new JButton("Cancel");
  c.gridx = 1;
  contentPane.add(cancelButton, c);
  }}
  
  LoginDialogView 包含了文本域,標簽,和按鈕元素。除了普通的GUI行為外,他只是有一個簡單的行為,被actionPerformed() 方法實現。這個行為就是當登錄按鈕被點擊后,login()方法被調用。假如登錄成功,對話框就被所調用的hide()方法所關閉。
  
  為了調用login()函數,在LoginDialogView 構造器里需要接收一個LoginDialog實例。另外,他組裝了完整的GUI設置和事件處理代碼。大部分代碼在addControls() 里,他簡單的創建和排版了窗體上的GUI元素。
  
  LoginDialogView 代碼示范了一個GUI瘦視圖元素怎樣被設計使它只包含普通的GUI代碼,而把重要的需要測試應用的行為放到一個單獨,可測試的靈敏對象中。
  
  LoginDialogView 只需要通過創建它來測試,察看他,從用戶的角度確認它看起來和運行起來象期望的那樣。例6展示了可執行的類APPMain,它創建了對話窗體來傳遞可用性測試(指的是傳遞loginDialog的實例)。
  
  AppMain.java
  
  public class AppMain {
  public static void main(String[] args) {
  AppMain app = new AppMain();
  }  public AppMain() {
  LoginDialog dialog = new LoginDialog();
  LoginDialogView view = new LoginDialogView(dialog);
  view.show();
  while (view.isVisible()) {
  try {
  Thread.currentThread().sleep(100);
  } catch(Exception x) {}
  }
  System.exit(0);
  }}
  
  AppMain 類簡單的創建一個LoginDialog 和LoginDialogView ,顯示視圖,休眠直到視圖關閉,然后退出。
  
  AppMain 象下面一樣運行
  
  java –classpath "." AppMain
  
  運行它創建登錄對話框,如圖4所示
  
  
 采用靈敏方法進行用戶界面開發(圖四)
  Figure 4. The login dialog window

  
  和登錄對話框交互驗證了用圖4所示的值登錄,會登錄成功然后窗體關閉。試著用其它的值登錄,窗體將保持打開,因為登錄失敗了。取消按鈕關閉窗體,就象窗體的關閉按鈕一樣。這個登錄對話框就如同設計的那樣運行。
  
  解決方案
  
  我們已經根據TDD創建了登錄對話框和一個靈敏對象/瘦視圖設計模式。得到了一個有很好構架和功能的程序。有功能的應用行為被單元測試所覆蓋,普通的用來顯示的代碼不需要復雜的GUI測試。圖5展示了我們所開發的這個軟件的構架。
  
  
 采用靈敏方法進行用戶界面開發(圖五)
  Figure 5. The classes LoginDialog, LoginDialogView, and LoginDialogTest
  

  基于此,其他的特性可以被加入。登錄對話框可以有一個消息域去提醒用戶登錄失敗。其他的登陸參數域也可以被加入。一個單獨的驗證對象可以被創建,硬編碼的登錄值可以被刪掉。不管怎么變化,TDD和靈敏對象/瘦視圖模式提供了一個設計和實現上的清楚的方向。重要的應用功能是在于可以測試的靈敏的對象,和在瘦視圖中普通的顯示用的代碼的。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91av视频在线播放| 国产欧美最新羞羞视频在线观看| 2019日本中文字幕| 国产不卡一区二区在线播放| 欧美中文在线观看| 亚洲精品日产aⅴ| 久久久久亚洲精品国产| 欧美与欧洲交xxxx免费观看| 红桃视频成人在线观看| 国产精品一区二区久久| 国产精品海角社区在线观看| 成人av色在线观看| 国产91精品网站| 亚洲欧洲偷拍精品| 91精品久久久久久久| 久久久视频在线| 国产成人精品久久亚洲高清不卡| 国产成人在线精品| 九九久久久久久久久激情| 亚洲区一区二区| 欧美另类精品xxxx孕妇| 国产精品久久国产精品99gif| 国产精品老女人精品视频| 九九热最新视频//这里只有精品| 久久久中精品2020中文| 亚洲第一天堂无码专区| 国产精品wwwwww| 国产一区二区三区在线观看网站| 91中文字幕在线| 国产欧美日韩综合精品| 91日韩在线播放| 欧美电影在线播放| 成人国产精品久久久久久亚洲| 国产精品福利小视频| 日韩欧美成人免费视频| 97精品久久久中文字幕免费| 日韩女优人人人人射在线视频| 精品亚洲aⅴ在线观看| 欧美最猛性xxxxx免费| 国产一区二区黑人欧美xxxx| 久久久久久网站| 国产香蕉一区二区三区在线视频| 91国偷自产一区二区三区的观看方式| 欧美亚洲视频在线观看| 国产乱肥老妇国产一区二| 日韩欧美精品中文字幕| 这里只有精品在线播放| 97在线视频国产| 国产一区二区黄| 欧美一区二区视频97| 国产亚洲美女精品久久久| 久久久久久高潮国产精品视| 日韩欧美精品免费在线| 中文字幕免费国产精品| 91在线视频精品| 亚洲自拍偷拍一区| 色噜噜狠狠狠综合曰曰曰| 欧美在线视频观看免费网站| 欧美乱大交xxxxx另类电影| 91社影院在线观看| 国产黑人绿帽在线第一区| 日韩av在线最新| 高清欧美一区二区三区| 亚洲欧美成人在线| 色诱女教师一区二区三区| 亚洲欧美国产精品久久久久久久| 懂色av影视一区二区三区| 久久久久久网站| 尤物99国产成人精品视频| 亚洲人成网站777色婷婷| 亚洲在线免费看| 国产一区二区三区免费视频| 久久久久久久一区二区| 国产精品久久久久久久av大片| 精品视频9999| 97在线视频免费看| 欧美成年人视频网站欧美| 一区二区在线免费视频| 国产精品一区久久| 精品国产鲁一鲁一区二区张丽| 亚洲最新中文字幕| 欧美在线视频观看免费网站| 亚洲激情中文字幕| 欧美午夜精品伦理| 久色乳综合思思在线视频| 久久久久久久久久av| 成人做爽爽免费视频| 91亚洲精品久久久| 亚洲深夜福利视频| 国内精品中文字幕| 亚洲人成毛片在线播放| 成人激情在线观看| 青青青国产精品一区二区| 欧美午夜片欧美片在线观看| 国产一区视频在线| 国产精品久久久久久久9999| 欧美老女人www| www.日韩.com| 亚洲激情免费观看| 成人国产精品一区| 成人久久18免费网站图片| 国产精品久久久久久久9999| 久久国产精彩视频| 亚洲欧美第一页| 欧美裸身视频免费观看| 国模精品视频一区二区三区| 欧美成人免费小视频| 国产在线视频一区| 亚洲电影免费观看高清完整版在线观看| 久久免费成人精品视频| 日本高清久久天堂| 亚洲a级在线播放观看| 精品久久久国产| 亚洲激情视频网站| 色香阁99久久精品久久久| 色哟哟网站入口亚洲精品| 国产精品国产三级国产专播精品人| 中文字幕日韩欧美| 欧美激情视频在线观看| 国产精品久久久久av免费| 91国内在线视频| 国产99久久精品一区二区| 国产日韩在线亚洲字幕中文| 欧美日韩国产精品一区| 欧美精品手机在线| 久久综合五月天| 国产一区二区精品丝袜| 亚洲成人网av| 日本精品免费一区二区三区| 亚洲精品有码在线| 精品久久久久人成| 欧美一级片免费在线| 麻豆成人在线看| 欧美成人国产va精品日本一级| 38少妇精品导航| 国产精品一区二区久久精品| 国产极品jizzhd欧美| 欧美午夜视频在线观看| 国产精品国产三级国产aⅴ9色| 久久青草精品视频免费观看| 欧美日韩在线视频一区| 久久成人综合视频| 国产精品日韩久久久久| 国产精品在线看| 欧美一级bbbbb性bbbb喷潮片| 九九久久国产精品| 欧美福利视频在线观看| 91精品视频免费观看| 亚洲片av在线| 91色视频在线观看| 福利视频一区二区| 欧美一区视频在线| 欧美与欧洲交xxxx免费观看| 成人网在线视频| 日本精品免费一区二区三区| 欧美尺度大的性做爰视频| 91老司机精品视频| 欧美国产亚洲精品久久久8v| 欧美精品www在线观看| 黄色精品在线看| 色与欲影视天天看综合网| 成人免费直播live| 久久五月天综合| 欧美最猛性xxxxx(亚洲精品)|