• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    見山只是山 見水只是水——提升對繼承的認識

    發布: 2007-5-25 11:48 | 作者: 溫 昱 | 來源: 互連網 | 查看: 35次 | 進入軟件測試論壇討論

    領測軟件測試網

    封裝、繼承、多態是OO的三大特性,由此可見繼承思想的重要性。但是,不少人對繼承的理解過多地局限在OOP層面,從而限制了繼承思想在OOD層面的巨大作用。筆者認為,軟件工程師應該不斷提升對OO思想的認識層面,加強實際開發能力。

    MILY: 宋體">本文站在OOD的角度,將繼承看成實現OOD的強大手段,通過具體例子,說明針對接口編程(Program To An Interface)、混入類(Mix In Class)、基于角色的設計(Rolebased Design)這三個與繼承緊密相關的著名OOD技巧。

     

     一、從一則禪師語錄說起

     

    《五燈會元》卷十七中,有一則青原惟信禪師的語錄:“老僧三十年前未參禪時,見山是山,見水是水。及至后來親見知識,有個入處,見山不是山,見水不是水。而今得個休歇處,依前見山只是山,見水只是水。”

    禪師高論,頗具哲理,講的是悟道的過程。其實,領悟OOD之道的過程又何嘗不是如此呢?

     

    1、見繼承是繼承——程序員境界

    初學OOP的人,大多處在“見繼承是繼承”的層面,最關心的是類的語法、類的成員變量、類的成員函數等這些實現層的東西。這是程序員境界。

     

    2、見繼承不是繼承——成長境界

    開始研習OOD之時,又往往跳到另一個極端,只關心設計,而無心(也可能是無力)關心實現,處在所謂“見繼承不是繼承”的層面。在這個階段的人,腦中的興奮點是“設計”,是職責分配、接口設計、可重用性、可擴展性、耦合度、聚合度等這些設計層的概念。這是成長境界。

     

    3、見繼承只是繼承——設計師境界

    學通OOD之后,會達到“見繼承只是繼承”的層面。一個“只”字,體現了繼承背后的“設計理念”才是該境界的要害。但是,這個階段和第二階段不同,第二階段是一味的否定,而本階段是否定之否定,把OOP層面的繼承機制看成用來實現特定OOD的手段加以利用。這是設計師境界。

      

    二、從OOD層面認識繼承

     

    OOP層面,除了類、成員變量、成員函數這些最基本的概念,最重要的就是代碼重用和名字空間的可見性了。而OOD層面,最基本的概念是類、職責、狀態、角色這些更抽象一級的概念,及其相關的耦合度、聚合度、可重用性、可擴展性、可維護性等?梢,雖然OOD最終要依賴OOP作為實現手段,但顯然OODOOP并非在同一抽象級上,有不同的概念體系和思維方式。

    再說繼承。單純從OOP層面看,繼承是一個通過復用父類功能而擴展應用功能的基本機制,它允許你根據舊的類快速定義新的類;還有些人用繼承僅為了獲取名字空間的可訪問性。但是,從OOD層面看,繼承可以演變出 “Is-A”、“Plays Role Of”等抽象的設計概念。因此,擔任設計師角色的人如果自己還限制在OOP的層面,“設計乏術”的局面是不可避免的?傊,提升對繼承的認識,對活用接口繼承和實現繼承這兩種繼承機制來實現OOD意圖非常重要。

    與繼承相關的OOD技巧有很多,本文僅討論比針對接口編程、混入類、基于角色的設計這三種技巧,下圖展示了它們和繼承的關系。

      

    三、針對接口編程——隔離變化

     

    1、相關理論

    耦合是依賴的同義詞,被定義為“兩個元素之間的一種關系,其中一個元素變化,導致另一個元素變化”。抽象耦合被定義為“若類A維護一個指向抽象類B的引用,則稱類A抽象耦合于B”。

    依賴性倒置原則(Dependency Inversion Principle)形式化了抽象耦合的概念,明確表述了應該“依賴于抽象類,不要依賴于具體類”。

    針對接口編程遵守上述原則,從而在很大程度上阻止了變化波及范圍的擴大,有效地隔離了變化,有助于增強系統的可重用性和可擴展性。

     

    2、針對接口編程舉例——用于體系結構設計

    根據經典的CoadOOD理論,一個項目通常包含四個層:用戶界面層、問題領域層、數據管理層、系統交互層,如下圖所示。

    將體系結構劃分為層的一個很大好處是,這些層形成了開發小組的自然分界——每層的開發人員所需要的技巧是不同的。用戶界面層的開發小組需要了解將使用的用戶界面工具包;數據管理層的開發小組需要熟悉相關的數據庫、持久工具或者使用的文件系統;系統交互層的開發小組需要了解通訊協議和用到的中間件產品;問題領域層的開發小組不需要了解這些知識,他們需要最深的領域知識,以及用到的相關分布對象或組件技術。

    但是,要真正使得各個開發小組最大限度地獨立開發,還需要一個穩定的體系結構設計做保證才行,其設計的核心思想是:問題領域層“不依賴于”其他任何層,而其他任何層“只依賴于”問題領域層。如下圖所示。

    該體系結構設計的實現,極為重要的一點,就是要使用針對接口編程的技巧。以系統交互層對問題領域層的單向依賴為例:

    Ø         如果系統交互層要調用問題領域層的操作,直接調用即可。

    Ø         如果問題領域層要調用系統交互層的操作,需要由問題領域小組定義一個通用的抽象接口,通過針對接口編程調用這個抽象接口;而系統交互小組通過接口繼承機制,定義抽象接口的子類,該子類完成抽象接口的具體實現。

    筆者曾有一個項目,該系統需要實時地將本系統的數據變化,通知遠端的另一個系統。相關設計如下圖所示。在問題領域層,僅包含了一個抽象接口CChangeReporter,而并不關心CChangeReporter的具體實現。系統交互層擁有選擇具體實現方法的自由,比如CSoapChangeReporter是用SOAP通訊協議實現的CChangeReporter, CTcpChangeReporter是用TCP協議實現的CChangeReporter。而且假設由于技術的或商業的原因,將來需要同時支持多種通訊協議,也比較容易。

     

    3、針對接口編程舉例——用于類設計

    筆者曾在《運用設計模式設計MIME編碼類》一文中,詳述了如何使用策略模式來設計一個可重用、易擴充的MIME類層次,其中抽象接口類CMimeAlgo起到了至關重要的作用,現簡述如下。

    用戶通過CMimeString使用MIME編碼的功能,CMimeString允許用戶在運行過程中動態配置MIME編碼的具體算法;具體MIME編碼算法由CMimeAlgo類層次提供,具體的CMimeAlgo子類的實例化是由CMimeString根據用戶的配置動態完成的;要增加新的MIME編碼算法,只需實現新的CMimeAlgo子類,并簡單擴充CMimeString的動態實例化代碼即可。如下圖所示。

     

    四、混入類——更好的重用性

     

    1、相關理論

    混入類被定義為“一種被設計為通過繼承與其他類結合的類”,它給其他類提供可選擇的接口或功能。

    從實現上講,混入類要求多繼承;混入類通常是抽象類,不能實例化。

    混入類的作用在于:它不僅可以提高功能的重用性,減小代碼冗余;而且還可以使相關的“行為”集中在一個類中,而不是分布到多個類中,避免了所謂的“代碼分散”和“代碼交織”問題,提高了可維護性。

     

    2、混入類舉例

    來看一個具體項目。在一個信用卡客戶服務系統項目中,要求能夠以多種方式發送多種信息給用戶,并能夠適應未來業務的發展變化。

    當前系統需要支持的發送方式:

    Ø         打。ú⑧]寄)

    Ø         Email

    Ø         傳真

    可預見的未來要支持的發送方式:

    Ø         手機短信

    Ø         PDA消息

    當前系統需要支持的待發送信息:

    Ø         信用卡對賬單

    Ø         信用卡透支催收單

    可預見的未來要支持的待發送信息:

    Ø         信用卡新業務宣傳單

    Ø         信用卡促銷活動宣傳單

    下面是一些設計考慮。一種發送方式要支持多種待發送信息,我們希望發送功能有很好的可重用性;為了方便未來加入對新的發送方式和發送信息的支持,設計必須具有良好的可擴展性。相關設計如下圖所示。其中采用了混入類的OOD技巧,用一個CSendableDoc作為混入類,支持發送功能的重用;CSendalbeDoc還采用了策略模式支持發送方式的擴充。

     

     

    五、基于角色的設計——使用角色組裝協作

     

    1、相關理論

    協作被定義為“多個對象為了完成某種目標而進行的交互”。角色被定義為“特定協作中的對象的抽象”,它“僅定義了對象特征的一個對某協作有意義的子集”。協作和角色的概念和現實世界很接近,比如下圖中,Jane教授扮演三個角色——母親、妻子、教授。

    接口分離原則(Interface Separation Principle)信奉“多個專用接口優于一個單一的通用接口”的思想,因為“任何接口都應當具有高內聚性”,以便“保證實現該接口的類的實例對象可以只呈現為單一的角色”。

    基于角色的設計的意義在于:我們很容易通過已有角色的組合來構造新的協作,以完成新的功能。而且,從UML類圖可以很自然地導出基于角色的設計方案,例如:

     

    從上面的類圖很自然地導出下面的設計:

    2、基于角色的設計舉例

    比如,待開發的一個系統,其后臺數據源可能是關系數據庫、一般的文件、還可能是另一個私有數據庫。既然接口可以隔離變化,我們可以定義一個單一的接口,為所有的數據客戶類提供服務。如下圖所示。

    但是,上面的設計違背了基于角色的設計思想,根本不能保證“實現該接口的類的實例對象可以只呈現為單一的角色”,這會帶來一些問題。比如,有一個數據客戶類,不需要插入、更新等功能,而僅僅需要對數據進行讀操作,這時顯然一個提供“讀”服務的“角色”是最合理的設計,但CRowSetManager卻是如此之“寬”的一個接口。最終,我們可以這樣來改進設計,如下圖所示。

     

    參考文獻:

    《設計模式》 Erich Gamma等著 李英軍等譯

    《重構——改善既有代碼的設計(影印版)》 Martin Fowler

    UML面向對象設計基礎》 Meilir Page-Jones著 包曉露等譯

    Java設計:對象、UML和過程》 Kirk Knoernschild著羅英偉 汪小林譯

    《特征驅動開發方法原理與實踐》Stephen R. Palmer, John M. Felsing著熊煥宇等譯

    Object-oriented programming: Role-based design W.McUmber 來自網上的幻燈片

    Role = Interface: A Merger of Concepts Friedrich Steimann 來自JOOP

    《運用設計模式設計MIME編碼類》 溫昱 CSDN開發高手》第1

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>