軟件框架設計的藝術----讀書總結

總結

軟件開發的藝術

理想主義,經驗主義和無緒

文藝復興時期,現代科學產生了兩個重量級理論: 理性主義和經驗主義。java

理性主義認爲理智是信息的首要來源。給出一個假設,只要經過思考就能理解和描述這個世界,如著名的伽利略自由落體實驗。mysql

經驗主義則認爲人類對世界認識的主要來源是經驗。程序員

咱們開一輛車,沒必要知道其內部實現細節。web

若是孤立地基於兩種極端的方式來觀察世界都是片面的。對大多數人來講,懵懂無知是一種生活方式,也是理性主義和經驗主義結合在一塊兒的結果。今天的程序開發和軟件工程方法也是如此。sql

軟件的演變過程

  1. 上世紀40年度,用機器語言, 那時debug的時候可能還得帶一個扳手
  2. 而後 FORTRAN ,他容許程序員只關心數學公式而不是內部機器內部實現 ---- 經驗主義
  3. 而後COBOL來了, 他簡化了數據庫的操做 ---- 經驗主義
  4. 固然同時期lisp出現了,他更強調純粹的數學模型---理性主義
  5. 而後cpp, 而後java

咱們能夠發如今軟件演變的過程當中, 理性主義幾乎已無存身之處。數據庫

由於軟件的趨勢是: 程序員在能夠不深刻了解不少內容的狀況下就能夠寫出很是好的代碼。編程

大型軟件是如何開發的

現狀: 開發團隊每每直接複用現有的一些軟件框架,徹底不重視這些重量級的框架是否超過咱們的須要的。現代軟件都是基於大型組件的方式進行組裝的。 我要一個web服務器就裝一個tomocat, 要一個數據庫就裝個mysql。 這徹底是一種推土機式的開發方式,無論你的組件有多大, 總會找到合適的推土機把他推上去。 運行效率太差 就 加內存,搞服務器集羣,windows

這種方法是好仍是壞呢?實際上絕大多數公司已經用這種方式了。api

由於推土機式的工做方式可使你在不關注內部細節的狀況下,也能夠獲得不錯的結果。 咱們能夠在不瞭解汽車原理的狀況下,能夠把汽車開得很好。 在寫win32程序時候,也沒必要了解系統是怎麼實現。 咱們只須要關注windows 系統API, 以及這些API的功能。緩存

理解一個系統有兩個層面:

  1. 淺層理解: 緊限於瞭解使用方法
  2. 深層理解: 理解其原理

而在軟件開發中, 通常只要作到淺層理解就能夠了。

咱們說明軟件開發實際上是一個經驗的積累過程,而且能夠是複用前人的經驗積累的。

設計API的動力之源

好的API可使功能的使用者聚焦在使用層面而不是其內部細節

爲何須要好的API:

  1. 分佈式開發: 一般咱們一個程序部署由一我的能獨立完成的
  2. 模塊化應用程序 : 咱們的程序是分模塊的,不一樣模塊的交互就是用API
  3. 交流互通才是一切: 模塊之間相互依賴
  4. 開發第一個版本一般比較容易

設計API過程當中遇到的最大問題--- 不斷變化的需求

一個軟件開發的生命週期:

  1. 初版吧老是很是漂亮的
  2. 快樂老是短暫的
  3. 軟件熵不斷增長
  4. 天哪 千萬不要動他
  5. 從新開發一個版本吧。

變化是萬惡之源。

那麼如何才能設計好的API

評價API好壞的標準

第一步先確認什麼才叫好。

不少人認爲所謂的API,不過是類和方法。可是這是比較片面的。

強調一點, 咱們爲何須要開發好的API:咱們但願可以將大塊的構建模塊,」無緒「地集合成應用程序。

那麼如何評價一個API的質量: 漂亮? 可是評價漂亮的標準是很主觀的。咱們應該設計易於使用、廣爲接受且富有成效的API。咱們能夠有一下幾個方面來衡量一個API的好壞。

  1. 可理解性: 每一個人的世界觀都會限制本身d視野,因此對於一個優秀的API來講,他涉及的概念都要在用戶的可理解範圍以內, 即便有新的概念也應該是漸進式的。
  2. 一致性: 向下維持兼容
  3. 可見性: 最好提供一個入口用來做爲用戶API的起點。 爲何你們都喜歡開源,由於開源不少東西網上能夠直接拷貝。
  4. 簡單的任務應該有簡單的方案: 因此API應該是分層的。
  5. 保護投資: 善待API的用戶。 儘可能想辦法讓API漂亮點。如方法名,如結構等。 在發佈初版以前這些都是很是合適的。可是發完初版之後咱們要保證我嗎的代碼改動不會影響正在運行的代碼了。

實現API的步驟

第二步弄清楚寫API的步驟

寫一個API有三個步驟:用例, 場景, 文檔。

一個用例就是一種用法的描述,他指出用戶可能要面臨的問題,而這個問題不是一個具體的問題,而是不少問題的抽象。

舉個例子

用例: 設計一個數據庫管理器,他的功能是註冊JDBC驅動。

場景:對用例的回答。咱們把API要描述的每個功能下列出來:

  1. 註冊有一個JDBC能夠寫一個可以描述驅動的XML, 有格式
  2. 這個XML放置在DataBase/JDBCDrivers目錄下
  3. 用URL來表示驅動地址

注意一些設計原則

第三步 學習一些設計原則和通用方法

  1. 只公開你要公開的內容
  2. 面向接口而非實現進行編程
  3. 模塊化架構
  4. 聲明式編程

只公開你要公開的內容

咱們所設計的API都會被可能誤用。幾乎全部的API設計者都會有這樣的共識:一我的API設計的時間越長,他設計的API公開的內容會越少。

設計API的幾種方法:

1. 方法優於字段

這個不用說了。 geter setter。 這樣作會有不少改變的餘地。 如計算、轉換、校驗、覆蓋

2.工廠方法優於構造函數

工廠方法會帶來很大的靈活性,三個好處:

  1. 返回不必定是聲明的類型能夠是子類
  2. 構造的對象能夠被緩存
  3. 同步的控制。 能夠都構造對象先後的代碼進行控制。
3. 讓全部的內容都不可改變

一般狀況下, 在設計一個類的時候,若是不考慮讓擁有子類,那就不該該讓這個類被繼承。 用final 來修飾。 還有些其餘方案來: 不公開構造函數轉而提供工廠方法。把大部分方法變爲final或者private

4. 避免濫用setter方法

一個寶貴的教訓: 如無必要,絕對不要再正式的API中聲明setter方法。

5. 儘量經過友元的方式來公開功能

在java中,所謂的友元就是用默認的package方式訪問,即容許同一個包內的代碼進行訪問。

有個實際的例子

6. 賦予對象建立者更多的權利
7. 避免暴露深層次繼承

避免深層次的繼承,定義程序的接口,並讓用戶來實現這些接口。 若是一個類繼承了某個類或者接口,那麼就能夠做爲響應的類或接口被使用。

如在swing中, frame間接繼承了compoment,這樣就表示全部使用compoment的地方,均可以使用frame. 實際上frame繼承 compoment是爲了複用compoment的代碼。這是一種典型的面向對象的複用的誤用。 因此若是發現繼承提醒超過2層,必定要想清楚「我是在設計API仍是在複用代碼」,若是是後者,則作好子類化準備。

面向接口而非實現進行編程

本質上講,這個原則倡導的是,當咱們寫一個函數或一個方法時,咱們應該引用相應的接口,而不是具體的實現類。接口提供了很是優秀的抽象概括,讓咱們的開發工做變得容易不少。 讓API的使用者和API的實現者解耦出來。

模塊化架構

隨着軟件規模的增大以及功能的複雜性增長。只要代碼開始訪問其餘無關模塊的內容,那麼架構的退化不可避免。模塊化能有效變緩這種退化。

模塊化的目的很是簡單,就是要實現程序中各個組成部分的鬆耦合。若是兩個模塊是獨立的,那兩個模塊就不須要知道對方的存在。若是兩個模塊要交互,那麼他們應該經過具備良好定義的接口來進行交互。

聲明式編程

聲明式編程的基本思路, 不是讓API用戶一步一步告訴程序如何作,而只是須要告訴程序他們要的結果,而後交給API去完成。聲明式編程的好處是能在較高的抽象層次來定義操做。

好比寫一個資源管理API: API的使用者很容易找到一個方法去註冊一個功能,運行一下成功了,而後再也不往下繼續找註銷的方法了。 聲明式編程就是解決這個問題的一劑良藥: 開發人員只須要聲明註冊什麼,響應的註銷和清理由系統完成。

極端的意見有害無益

最後提醒一點,任何極端的想法都是有害的,在軟件框架設計中也同樣, 有如下單不只限幾個點:

  1. API必須是漂亮的
  2. API必須是正確的: 有時候易用性和正確性還重要。好比巨大文件
  3. API應該儘可能簡單
  4. API必須是高性能
  5. API必須絕對兼容
  6. API必須是對稱的

團隊協做

現代的大型工程不多是有一我的單獨開發完成的,因此團隊協做很是重要。一下幾個點能很好幫助在大型軟件工做中完成好的API設:

  1. 在提交代碼時候進行代碼審覈
  2. 爲API提供文檔
  3. 盡職盡責的監控者
  4. 接受API的補丁

以上很是簡單,可是在外面日常工做中缺乏的就是執行。

相關文章
相關標籤/搜索