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

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
使用 SDAO 進行 J2EE 測試的分步方法
使用模擬和實際數(shù)據(jù)訪問對象來有效而又高效地測試 J2EE 應用程序

 

數(shù)據(jù)訪問對象(Data Access Object)模式已經(jīng)成為 J2EE 開發(fā)人員工具庫中的標準部件。大多數(shù)開發(fā)人員不知道它有一個變體可以使測試更輕松。 模擬數(shù)據(jù)訪問對象集中了 DAO、模仿對象和分層測試的精華,從而允許您同時改進測試結(jié)果和整體開發(fā)方法。企業(yè) Java 開發(fā)人員(并且是 SDAO 大師)Kyle Brown 使用代碼樣本和討論向您全面介紹 SDAO 的概念和日常用法。

今年早些時候,我在北卡羅萊納州立大學(North Carolina State University)給一群研究生作了一個關(guān)于 J2EE 技術(shù)的演講。我提供了一個說明 servlet 和 JSP 用法的樣本設計,以說明如何結(jié)合 MVC 方法和簡單數(shù)據(jù)訪問對象(DAO)以處理應用程序中持久數(shù)據(jù)的查詢和更新。在陳述這些材料時,我看到聽眾們會心地微笑和點頭。但是,在陳述結(jié)束之后,我收到了一個學生的電子郵件。為什么我實現(xiàn)的 DAO 不止一個,而是兩個,又為什么設置了一個 Factory 類以允許在它們之間進行選擇呢?

這很令人費解,但是我很快意識到了問題所在:我忘了告訴那些學生,我正在實現(xiàn) MVC 和 DAO 之外的第三種模式。尤其是,我的設計利用了模仿對象來簡化測試。在我考慮 DAO 的方式中,模仿對象是很基本的,以致我無法想象在缺少其中一個的情況下如何實現(xiàn)另一個。進一步說,我自動地調(diào)整了設計,以便使測試更容易,這對許多經(jīng)驗豐富的開發(fā)人員和我的學生們都是一個同樣陌生的概念。

在本文中,您將了解使用模擬數(shù)據(jù)訪問對象(SDAO)進行分層測試。與模仿對象一樣,SDAO 用專門為測試開發(fā)的對象取代現(xiàn)有對象。但是,與模仿對象不同的是,不需要對 SDAO 提供檢測以包含測試斷言。SDAO 模式的目的是允許您將一個層(域?qū)ο髮樱┖土硪粋€層(數(shù)據(jù)訪問層)隔離開。我們將從回顧數(shù)據(jù)訪問對象模式入手。

關(guān)于模式的只言片語
閱讀更多有關(guān)模式如何向開發(fā)人員提供共享設計詞匯表的內(nèi)容。

數(shù)據(jù)訪問對象
數(shù)據(jù)訪問對象模式的目的是提供到特定數(shù)據(jù)源的單個聯(lián)系點。與許多設計模式相似,DAO 以分隔設計任務為基礎。具體來說,DAO 將業(yè)務邏輯與數(shù)據(jù)庫持久性代碼分隔開來。數(shù)據(jù)訪問對象負責對持有數(shù)據(jù)(存儲在關(guān)系數(shù)據(jù)庫中)的對象進行操作。DAO 所操作的對象通常稱為 值對象,盡管術(shù)語 數(shù)據(jù)傳送對象(data transfer object,DTO)的意思更為貼切。

DAO 類通常包含對其 DTO 進行操作的 CRUD 方法,即 create() 、 read() 、 update()delete() 。例如,假定我們正在構(gòu)建一個登記會議出席人員的系統(tǒng)。我們的 DAO 類接口可能如清單 1 中所示:

清單 1. 示例 DAO 類接口
public interface AttendeeDAO {            public void createAttendee(Attendee person) throws DAOException;            public void updateAttendee(Attendee person) throws DAOException;            public Collection getAllAttendees() throws DAOException;            public void deleteAttendee(Attendee person) throws DAOException;            public Attendee findAttendeeForPrimaryKey(int primaryKey)            throws DAOException;            

聲明這個接口(或與它類似的接口)是實現(xiàn) DAO 模式的標準部分。具體的 DAO 應用程序?qū)崿F(xiàn)如圖 1 中所示的接口:

圖 1. 示例 DAO 應用程序

消息處理
在大多數(shù)情況下,類似于上述示例的 DAO 應用程序會使用 JDBC 進行數(shù)據(jù)庫訪問。例如,在 getAllAttendees() 方法的示例中,該類將獲取一個到數(shù)據(jù)庫的連接,查詢數(shù)據(jù)庫以獲取 Attendee 表中的行列表,迭代從查詢返回的 ResultSet ,然后為 ResultSet 中每一行構(gòu)造 Attendee 對象。

請參閱 參考資料以獲取 DAO 模式的深入討論和示例。

模擬數(shù)據(jù)訪問對象
模擬數(shù)據(jù)訪問對象實際上模擬后端數(shù)據(jù)存儲。實現(xiàn) SDAO 模式使我們能夠測試各種應用程序?qū)樱ㄈ鐦I(yè)務邏輯和 GUI),而無需恰好擁有實際的數(shù)據(jù)庫。

以下是使用 SDAO 進行分層測試的一些具體優(yōu)點:

  • 便宜:使用模擬數(shù)據(jù)庫進行測試和調(diào)試使您節(jié)省了在每個開發(fā)人員的桌面上安裝 DB2(比方說)的成本。
  • 容易:即使不必處理數(shù)據(jù)庫錯誤,構(gòu)建具有 servlet、JSP 文件和 EJB 組件的應用程序也夠復雜的了。分層測試允許您設計出表示和業(yè)務邏輯,而不必同時擔心后端數(shù)據(jù)庫。
  • 迅速:按層進行分隔允許您在出現(xiàn)問題時隔離它們,這使得調(diào)試周期更快。有些錯誤(如 TransactionRollbackException )難以定位;從綜合體中除去數(shù)據(jù)庫層讓您更快地找出真實的問題。
  • 靈活:SDAO 可以用于性能概要分析和測試。盡管有些類型的性能問題(如數(shù)據(jù)庫死鎖)需要實際的數(shù)據(jù)庫來解決,但 SDAO 讓您獲得僅域和 GUI 性能的測量結(jié)果,然后可以利用這些結(jié)果來解決那些層上的問題。

SDAO 實戰(zhàn)
理解 SDAO 如何工作的最佳方法是實際研究它,并希望您親自應用它。我們將從模擬數(shù)據(jù)訪問對象的簡單示例入手,如清單 2 所示:

清單 2. DefaultDAO
public class DefaultDAO implements AttendeeDAO {            private static DefaultDAO instance = new DefaultDAO();            private Vector attendees = new Vector();            /**            * @see AttendeeDAO#createAttendee(Attendee)            */            public void createAttendee(Attendee person) throws DAOException {            getAllAttendees().add(person);            }            /**            * @see AttendeeDAO#updateAttendee(Attendee)            */            public void updateAttendee(Attendee person) throws DAOException {            Attendee match =            findAttendeeForPrimaryKey(person.getAttendeeKey());            attendees.remove(match);            attendees.add(person);            }            /**            * @see AttendeeDAO#getAllAttendees()            */            public Collection getAllAttendees() throws DAOException {            return getAttendees();            }            /**            * @see AttendeeDAO#deleteAttendee(Attendee)            */            public void deleteAttendee(Attendee person) throws DAOException {            Attendee match =            findAttendeeForPrimaryKey(person.getAttendeeKey());            attendees.remove(match);            attendees.add(person);            }            /**            * Gets the attendees            * @return Returns a Vector            */            public Vector getAttendees() {            return attendees;            }            /**            * Sets the attendees            * @param attendees The attendees to set            */            public void setAttendees(Vector attendees) {            this.attendees = attendees;            }            /**            * Gets the instance            * @return Returns a DefaultDAO            */            public static DefaultDAO getInstance() {            return instance;            }            /**            * Sets the instance            * @param instance The instance to set            */            public static void setInstance(DefaultDAO anInstance) {            instance = anInstance;            }            public Attendee findAttendeeForPrimaryKey(int primaryKey)            throws DAOException {            Enumeration enum = attendees.elements();            while (enum.hasMoreElements()) {            Attendee current = (Attendee) enum.nextElement();            if (current.getAttendeeKey() == primaryKey)            return current;            }            throw new DAOException("Primary Key not found "            + primaryKey);            }            }            

現(xiàn)在來看一下,這是晦澀的火箭科學,是嗎? DefaultDAO 類在靜態(tài)變量 instance 中存儲了它自己的一個實例(存儲為 Singleton),并允許通過 getInstance() 方法訪問該實例。然后,該類的用戶可以在 Singleton 實例保存的集合中添加和刪除 Attendee 元素,或替換集合中的元素。

對象工廠
要使這種技術(shù)在實際工作中有效,需要能夠?qū)⒊绦蛑械?#8220;實際”DAO 類替換成新的“模擬”DAO 類。我們的客戶機代碼本身不能引用 Db2AttendeeDAO 類或 DefaultDAO 類。因此我們使用 Factory 類(又名對象工廠),以根據(jù)需要為客戶機代碼提供 Db2AttendeeDAODefaultDAO 實例。

我們的對象工廠相當簡單。它只返回兩個類實例,用一種軟件“開關(guān)”(如 getAttendeeDAO() 方法中所示)在兩者之間進行切換。這個開關(guān)還可以檢查 System 特性的值,或檢查一些其它全局值,如清單 3 所示:

清單 3. AttendeeDAOFactory
            public class AttendeeDAOFactory {            public static AttendeeDAO getAttendeeDAO() {            String mode = (String) System.getProperty("TestMode");            if (mode.equals("Simulated"))            return DefaultDAO.getInstance();            else            return new DbAttendeeDAO();            }            }            

當您運行測試時,通常首先將 Factory 開關(guān)設置成返回模擬類。這樣做確保您可以在與數(shù)據(jù)庫隔離的情況下測試系統(tǒng)的其余層。只有在后面的測試中才會將開關(guān)設置成返回“實際”DAO。圖 2 使您對最終設計(包括 Factory 類)有一些了解,有可能如下所示:

圖 2. 示例 SDAO 實現(xiàn)

高級 SDAO
在您理解了基本的 SDAO 實現(xiàn)之后,就可以研究其它使用模擬 DAO( DefaultDAO )類的方法。迄今為止,您所看到的只是最簡單的實現(xiàn),其中的結(jié)果取自內(nèi)存中的集合,該集合在測試期間必須被填充。這種思想的常見擴展是在類的構(gòu)造函數(shù)中預先用缺省值填充該集合。正如我們在此所做的,使用 Singleton 的主要缺點是:您必須在各次測試之間清除 Singleton。如果您在某次測試時忘了這樣做,則會導致后面的測試失敗。幸運的是,大多數(shù)單元測試框架(如 JUnit)提供了輕松進行此類測試的工具。例如,在 JUnit 中,可以將清除 Singleton 的代碼放入測試類的 teardown() 方法中,并將任何執(zhí)行預先填充工作的代碼放到該測試類的 setUp() 方法中。

第二種方法略微復雜些,但也是為更實際的測試所提供的,這就是使用 Java 序列化或 XML 從文件讀取一組對象。這兩種技術(shù)都允許您使用幾個文件來表示同一個測試的不同初始條件。

我經(jīng)常在 SDAO 測試中使用“分兩步走”的方法。我構(gòu)建的第一個 DAO 是“缺省”DAO;它轉(zhuǎn)至 DTO 內(nèi)存中集合,然后被傳遞給構(gòu)建應用程序中上層部分(例如 servlet 和 JSP 文件)的團隊。然后我和另一個團隊一起構(gòu)建將實際使用數(shù)據(jù)庫的 DAO。這種方法允許兩個團隊同時工作,他們的交互是由 DAO 接口的共享約定定義的。

結(jié)束語
在 IBM WebSphere 軟件服務組(Software Services for WebSphere group)中,我們已經(jīng)成功地將本文描述的分層測試技術(shù)應用到了數(shù)十個客戶合作項目中。除了改進我們的整個產(chǎn)品之外,SDAO 還成為了幫助我們團隊掌握各種 J2EE API 特性的重要工具。使用模擬和實際 DAO 使我們可以在應用程序的許多層上同時工作,而不會被一次性地將所有部分組裝到一起的復雜情況所“嚇倒”。

作者衷心地感謝 Stacy Joines 和 Ken Hygh 對本文提出的有益建議。

參考資料

  • 您可以參閱本文在 developerWorks 全球站點上的 英文原文.

  • 對設計模式感到好奇嗎?可以從“四人組(Gang of Four)”的 Design Patterns:Elements of Reusable Object Oriented Software (由 Erich Gamma、Richard Helms、Ralph Johnson 和 John Vlissides 合著;Addison-Wesley,1995 年)入手。

  • 除了 Design Patterns以外, Core J2EE Patterns:Best Practices and Design Strategies (由 Deepak Alur、John Crupi 和 Dan Malks 合著;Addison-Wesley,2001 年)也是 J2EE 開發(fā)人員的必讀書籍。

  • Martin Fowler 的 Patterns of Enterprise Application Architecture (Addison-Wesley,2002 年)是企業(yè)開發(fā)模式的另一本全面介紹。

  • 您也可能想查看 Paul Monday 的“ java 設計模式201”( developerWorks,2002 年 4 月),這是一篇適合于設計模式愛好者的高級教程。

  • Bruce Whitenack 和 Kyle Brown 共同編寫了 Crossing Chasms,這是一種用于關(guān)系數(shù)據(jù)庫和 smalltalk 的模式語言。您可以在 Kyle 的 主頁上了解其開發(fā)(以及 Kyle 的其它項目)。

  • 通過 Kyle Gabhart 的 J2EE 探索 系列( developerWorks)以了解更多關(guān)于本文簡要提及的企業(yè)編程技術(shù)的信息。

  • Endo-Testing:Unit Testing with Mock Objects”(由 Tim Mackinnon、Steve Freeman 和 Philip Craig 合著;XP2000)是一篇有關(guān)單元測試和模仿對象的很棒的介紹 ― 并且它是第一篇關(guān)于這個主題的文章。

  • Sourceforge 目前保存著 Kent Beck 和 Erich Gamma 有關(guān)使用 JUnit 進行單元測試的介紹,“ Test Infected:Programmers Love Writing Tests”( Java Report,1998 年 7 月)。

  • Alexander Day Chaffee 和 William Pietri 的“ 使用模仿對象進行單元測試”( developerWorks,2002 年 11 月)向您展示了如何使用工廠模式來增強利用模仿對象的測試。

  • Malcolm Davis 的“ 利用 Ant 和 JUnit 進行增量開發(fā) ”( developerWorks,2000 年 11 月)讓您對單元測試有另一番了解,同時無形中又為您的工具箱增加了一種新技術(shù)。

  • 您可以將模仿對象測試與各種技巧和技術(shù)組合起來。Nicholas Lesiecki 的“ AspectJ 和模仿對象的測試靈活性”( developerWorks,2002 年 5 月)向您展示了模仿對象和面向方面(Aspect)的編程是如何一起工作的。

  • 您可以在 developerWorksJava 技術(shù)專區(qū) 中找到許多關(guān)于 Java 編程各方面的文章。

 

關(guān)于作者
Kyle Brown 是 IBM WebSphere 軟件服務部(Software Services for WebSphere)的高級技術(shù)組成員。Kyle 向財富 500 強客戶提供關(guān)于面向?qū)ο笾黝}和 Java 2 企業(yè)版(J2EE)技術(shù)的咨詢服務、培訓和指導。他與別人合著了 Enterprise Java Programming with IBM WebSphere 、 WebSphere 4.0 AEs Workbook for Enterprise JavaBeans(第 3 版) The Design Patterns Smalltalk Companion 。他還經(jīng)常在研討會上發(fā)表關(guān)于企業(yè) Java、OO 設計和設計模式的演講。您可以通過 mailto:brownkyl@us.ibm.com?subject=Stepped approach to J2EE testing with SDAO與他聯(lián)系。
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
9.2 Access中VBA的數(shù)據(jù)庫編程[2] - Access
學習筆記之ORM設計中用到的模式
ADO簡介
模式與J2EE
JAVA中Action層,Service層,modle層和Dao層的功能區(qū)分
結(jié)合SPRING 2.0使用JAVA PERSISTENCE API
更多類似文章 >>
生活服務
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服