第五章第一節 可複用性的度量、形態和外部觀察
本節探討可複用軟件的形態與特徵,下一節學習「如何構造」。 java
Outline
- 什麼是軟件複用
- 可複用實現的級別
- 源代碼級別的複用
- 模塊級別的複用:類、抽象類、接口
- 庫級別的複用:API、包
- 系統級別的複用:框架
- 對可複用性的外部觀察
- 白盒框架和黑盒框架
Notes
## 什麼是軟件複用
- 軟件複用是使用現有軟件組件實施或更新軟件系統的過程。
- 軟件複用的兩個觀點:
- 面向複用編程(programming for reuse):開發出可複用的軟件
- 開發成本高於通常軟件的成本:要有足夠高的適應性
- 性能差些: 針對更普適場景,缺乏足夠的針對性
- 基於複用編程(programming with reuse):利用已有的可複用軟件搭建應用系統
- 可複用軟件庫,對其進行有效的管理
- 每每沒法拿來就用,須要適配
- 爲何須要複用:
- 複用下降成本和開發時間
- 複用的代碼通過充分測試,可靠、穩定
- 產出標準化,在不一樣應用中保持一致
- 軟件複用的代價:
- 軟件可複用的部分須要設計在以下的標準上:明確的定義、開放的方法、簡潔的交互規範、可理解的文檔,並着眼於將來。
- 不只program for reuse代價高,program with reuse代價也高
- 代碼複用的類型:
- 白盒複用:源代碼可見,可修改和擴展
- 含義:複製已有代碼到正在開發的系統,進行修改
- 優勢:可訂製化程度高
- 缺點:對其修改增長了軟件的複雜度,且須要對其內部充分的瞭解
- 黑盒服用:源代碼不可見,不能修改
- 含義:只能經過過API接口來使用,沒法修改代碼
- 優勢:清晰、簡單
- 缺點:適用性差
- 高複用性的軟件應具備以下特性:
- 小、簡單
- 與標準兼容
- 靈活可變
- 可擴展
- 泛型、參數化
- 模塊化
- 變化的局部性
- 穩定
- 豐富的文檔和幫助
- 栗子:JDK中可複用的庫和API
## 可複用實現的級別
【源代碼級別的複用】git
相關研究1:如何從互聯網上快速找到須要的代碼片斷? 程序員
反向研究:如何從源代碼中檢測出克隆代碼(clone code)?github
咱們能夠在如github和searchcode的網站上搜索代碼,實現複用。編程
【模塊級別的複用:類、抽象類、接口】設計模式
- 複用類:
- 源碼並不是是必要的,可能只須要類文件或jar
- 只須要將這個類加入到類路徑
- 可使用工具javap得到一個類的public方法
- 使用複用類的注意事項:
- 文檔十分重要
- 壓縮會有助於複用
- 管理更少的代碼
- 版本兼容性
- 須要和類相關的包
- 複用類的方法:繼承和委派
- 繼承(Inheritance):
- 類擴展了現有類的屬性/行爲;
- 另外,他們可能會
Override
現有的行爲;
- 一般須要在實施以前設計繼承層次結構;
- 委派(Delegation):
- 根本沒有父子關係的類中使用繼承是不合理的,能夠用委派的方式來代替。
- 委託是簡單的將一個對象鏈接到另外一個對象上,使另外一個對象得到這個對象方法的子集(一個實體將某個事物傳遞給另外一個實體)。
- 明確的委託:明確將須要傳的對象傳到目標對象上
- 含蓄的委託:委託能夠被描述爲一種共享代碼數據的低級別機制
- 委派的類型:
- Use(A uses B)
- Composition/aggregation (A owns B)
- Association (A has B)
【庫級別的複用:API/包】框架
- 方法:Libaray、framework
- library:
- 庫定義:一組提供可重用功能的類和方法(API)
- 開發者構造可運行軟件實體,其中涉及到對可複用庫的調用
- Java中有不少的庫能夠複用,例如Guava:Google的Java核心庫;Apache Commons等
- framework:
- 框架定義:一組具體類、抽象類、及其之間的鏈接關係
- 做爲主程序加以執行,執行過程當中調用開發者所寫的程序
- 開發者根據 framework的規約,填充本身的代碼進去,造成完整系統
【系統級別的複用:框架】ide
將framework看做是更大規模的API複用,除了提供可複用的API,還將這 些模塊之間的關係都肯定下來,造成了總體應用的領域複用。開發者的任務就是增長新代碼、對抽象類進行具體化。展開來講就是如下幾點:模塊化
- 一般經過選擇性覆蓋來擴展框架; 或者程序員能夠添加專門的用戶代碼來提供特定的功能—定義繼承了抽象類祖先操做的具體類
- 設計模式(Hook方法),它被應用程序覆蓋以擴展框架。 Hook方法系統地將應用程序域的接口和行爲與應用程序在特定上下文中所需的變體解耦。
- 控制反轉,由第三方的容器來控制對象之間的依賴關係,而非傳統實現中由代碼直接操控。由第三方的容器來控制對象之間的依賴關係,而非傳統實現中由代碼直接操控。
- 不可修改的框架代碼:在接受用戶實現的擴展時,框架代碼不該該被修改。 換句話說,用戶能夠擴展框架,但不該修改其代碼。
## 對可複用性的外部觀察
- Type Variation 類型可變
- 可以複用的部分應該類型參數化,以適應不一樣的數據類型
- 複用的部分應該通常化
- 適應不一樣的類型,且知足LSP
- Implementation Variation 實現可變
- ADT 有多種不一樣的實現,提供不一樣的representations 和abstract function ,但具備一樣的specification (pre-condition, post-condition, invariants) ,從而能夠適應不一樣的應用場景
- Routine Grouping 功能分組
- 提供完備的細粒度操做,保證功能的完整性,不一樣場景下複用不一樣的操做( 及其組合)
- Representation Independence 表示獨立
- Factoring Out Common Behaviors 共性抽取
## 白盒框架和黑盒框架
框架也可分爲白盒框架和黑盒框架兩類。 工具
- 白盒框架:
- 經過繼承和動態綁定實現可擴展性。
- 經過繼承框架基類並重寫預約義的hook方法來擴展示有功能。
- 一般使用模板方法模式等設計模式來覆蓋hook方法。
- 黑盒框架:
- 經過爲可插入框架的組件定義接口來實現可擴展性。
- 經過定義符合特定接口的組件來複用現有功能。
- 這些組件經過委派(Delegation)與框架集成。