【轉載】如何寫一個框架:步驟(下)

說明:寫本文的時候做者徹底是把腦子裏的東西寫了出來,沒有參考任何的資料,因此對於每一項內容可能都是不完整的,不能做爲一個完整的參考。有一些方法學的東西每一個人都有本身的喜愛,沒有以爲的對和錯。 html

單元測試

在這以前咱們寫的框架只能說是一個在最基本的狀況下可使用的框架,做爲一個框架咱們沒法預測開發人員未來會怎麼使用它,因此咱們須要作大量的工做來確保框架不但各類功能都是正確的,並且仍是健壯的。寫應用系統的代碼,大多數項目是不會去寫單元測試的,緣由不少:緩存

  1. 項目趕時間,連作一些輸入驗證都沒時間搞,哪裏有時間寫測試代碼。
  2. 項目對各項功能的質量要求不高,只要能在標準的操做流程下功能可用便可。
  3. 項目基本不會去改或是臨時項目,一旦測試經過以後就始終是這樣子了,沒有迭代。
  4. ……

對於框架,偏偏相反,沒有配套的單元測試的框架(也就是僅僅使用人工的方式進行測試,好比在main中調用一些方法觀察日誌或輸出,或者運行一下示例項目查看各類功能是否正常,是很是可怕的)緣由以下:安全

  1. 自動化程度高,迴歸須要的時間短,甚至能夠整合到構建過程當中進行,這是人工測試沒法實現的。
  2. 框架必定是有很是多的迭代和重構的, 每一次修改雖然只改了A功能,可是可能會影響到B和C功能,人工測試的話你可能只會驗證A是否正常,容易忽略B和C,使用單元測試的話只要全部功能都有覆 蓋,那麼幾乎不可能遺漏由於修改致使的潛在問題,並且還能反饋出來由於修改致使的兼容性問題。
  3. 以前說過,一旦框架開放出去,框架的使用者可能會以各類方式在各類環境來使用你的框架,環境不一樣會形成不少怪異的邊界輸入或非法輸入,須要使用單元測試對代碼進行嚴格的邊界測試,以確保框架能夠在嚴酷的環境下生存。
  4. 單元測試還能幫助咱們改善設計,在寫單元測試的時候若是發現目標代碼很是難以進行模擬難以構建有效的單元測試,那麼說明目標代碼可能有強依賴或職責過於複雜,一個被單元測試高度覆蓋的框架每每是設計精良的,符合高內聚低耦合的框架。

若是框架的時間需求不是特別緊的話,單元測試的引入能夠是走通主線流程的階段就引入,越早引入框架的成熟度可能就會越高,之後重構返工的機會會越 小,框架的可靠性也確定會大幅提升。以前我有寫過一個類庫項目,並無寫單元測試,在項目中使用了這個類庫一段時間也沒有出現任何問題,後來花了一點時間 爲類庫寫了單元測試,出乎我意料以外的是,個人類庫提供的全部API中有超過一半是沒法經過單元測試的(原覺得這是一個成熟的類庫,其實包含了數十個 BUG),甚至其中有一個API是在個人項目中使用的。你可能會問,爲何在使用這個API的時候沒有發生問題而在單元測試的時候發生問題了呢?緣由以前 提到過,我是框架的設計者,我在使用類庫提供的API的時候是知道使用的最佳實踐的,所以我在使用的時候爲類庫進行了一個特別的設置,這個問題若是不是通 過單元測試暴露的話,那麼其它人在使用這個類庫的時候基本都會遇到一個潛在的BUG。網絡

示範項目

寫一個示例項目不只僅是爲了給別人參考,並且還可以幫助本身去完善框架,對於示例項目,最好兼顧下面幾點:多線程

  1. 是一個具備必定意義的網站或系統,而不是純粹爲了演示特性而演示。這是由於,不少時候只有那些真正的業務邏輯纔會暴露出問題,演示特性的時候咱們老是有一些定勢思惟會規避不少問題。或者能夠提供兩個項目,一個純粹演示特性,一個是示例項目。
  2. 覆蓋儘量多的特性或使用難點,在項目的代碼中提供一些註釋,不少開發人員不喜歡閱讀文檔,反而喜歡看一下示例項目直接上手(模仿示例項目,或直接拿示例項目中的代碼來修改)。
  3. 項目中的代碼,特別是涉及到框架使用的代碼必定要規範,緣由上面也說了,做爲框架的設計者你不會但願你們複製的代碼粘帖的代碼一團糟吧。
  4. 若是你的項目針對的不只僅是Web項目,那麼示例項目最好提供Web和桌面兩個版本,一來你本身容易發現由於環境不一樣帶來的使用差別,二來能夠給予不一樣類型項目不一樣的最佳實踐。

完善日誌和異常

一個好的框架不但須要設計精良,日誌和異常的處理是否到位也是很是重要的標準,這裏有一些反例:併發

  1. 日誌的各類級別的使用沒有統一的標準,甚至是永遠只使用某個級別的日誌。
  2. 幾乎沒有任何的日誌,框架的運行徹底是一個黑盒。
  3. 記錄的日誌多且沒有實際含義,只是調試的時候用來觀察變量的內容。
  4. 異常類型只使用Exception,不使用更具體化的類型,沒有自定義類型。
  5. 異常的消息文本只寫"錯誤"字樣,不寫清楚具體的問題所在。
  6. 永遠只是拋出異常,讓異常上升到最外層,交給框架的使用者去處理。
  7. 用異常來控制代碼流程,或本應該在方法未達到預期效果的時候使用異常卻使用返回值。

其實我的以爲,一個框架的主邏輯代碼並不必定是最難的,最難的是對一些細節的處理,讓框架保持一套規範的統一的日誌和異常的使用反而對框架開發者來講是一個難點,下面是針對記錄日誌的一些建議:框架

  1. 首先要對框架使用的日誌級別有一個規範,好比定義:
    1. DEBUG:用於觀察程序的運行流程,僅在調試的時候開啓
    2. INFO:用於告知程序運行狀態或階段的變化,能夠在測試環境開啓
    3. WARNING:用於告知程序能夠本身恢復的錯誤或異常,或不影響主線流程執行的錯誤或問題,能夠在正式環境開啓
    4. ERROR:用於告知程序沒法恢復,主線流程中斷,須要開發或運維人員知曉干預的錯誤或異常,須要在正式環境開啓
  2. 按照上面的級別規範,在須要記錄日誌的地方記錄日誌,除了DEBUG級別的日誌其它日誌不能記錄過多,若是框架老是在運行的時候輸出幾十個WARNNING也容易讓使用者忽略真正的問題。
  3. 日誌記錄的消息須要是明確的,最好包含一些上下文信息,好比"沒法在xxx下找到配置文件xxx.config,框架將採用默認的配置",而不是"加載配置失敗!"

下面是一些針對使用異常的建議:運維

  1. 框架因爲配置錯誤或使用錯誤或運行錯誤,不能完成API名字所表示的功能,考慮拋出轉化後的異常,讓調用者知道發什麼了什麼狀況,同時框架能夠創建本身的錯誤處理機制
  2. 對於能夠預料的錯誤,而且錯誤類型能夠枚舉,考慮以返回值的形式告知調用者能夠根據不一樣的結果來處理後續的邏輯
  3. 對於框架內部功能實現上遇到的調用者無能力解決的錯誤,若是錯誤能夠重試或不影響返回,能夠記錄警告或錯誤日誌
  4. 能夠爲每個模塊都陪伴自定義的異常類型,包含相關的上下文信息(好比ViewException能夠包含ViewContext),這樣出現異常能夠很方便知曉是哪一個模塊出現問題而且能夠獲得出現異常時的環境信息
  5. 若是異常跨了實現層次(好比從框架到應用),那麼最好進行一下包裝轉換(好比把文件讀取失敗的提示改成加載配置文件失敗的提示),不然上層人員是不知道怎麼處理這些內部問題的,內部問題須要由框架本身來處理
  6. 異常的日誌中能夠記錄和當前操做密切相關的參數信息,好比搜索的路徑,視圖名等等,有關方法的信息不用過多記錄,異常通常都帶有調用棧信息
  7. 若是可能的話,出現異常的時候能夠分析一下爲何會出現這樣的問題,在異常信息中給一些解決問題的建議或幫助連接方便使用者排查問題
  8. 異常處理從壞到好的層次是,出現了嚴重問題的時候:
    1. 使用者什麼都不知道,程序的完整性和邏輯獲得破壞
    2. 使用者既不知道出現了什麼問題也不知道怎麼去解決
    3. 使用者能明確知道出現了什麼問題,但沒法去解決
    4. 使用者不但知道發生了什麼,還能經過異常消息的引導快速解決問題

完善配置

配置的部分能夠留到框架寫的差很少了再去寫,由於這個時候已經能夠想清楚哪些配置是:分佈式

  1. 須要公開出去給使用者配置的,而且配置會根據環境不一樣而不一樣
  2. 須要公開出去給使用者來配置的,配置和部署環境無關
  3. 僅僅須要在框架內供框架開發人員來配置的
  4. 無需是一個配置,只要在代碼中集中存儲這個設定便可

通常來講配置有幾種方式:ide

  1. 經過配置文件來配置,好比XML文件、JSON文件或property文件
  2. 經過註解或特性(Annotation/Attribute)方式(對類、方法、參數)進行配置
  3. 經過代碼方式進行配置(好比單獨的配置類,或實現配置類或調用框架的配置API)

不少框架提供了多種配置方式,好比Spring MVC同時支持上面三種方式的配置,我的以爲對配置,咱們仍是應該區別對待,而不是無腦把全部的配置項都同時以上面三種方式提供配置,咱們要考慮高內聚和 低耦合原則,對於Web框架來講,高內聚須要考慮的比低耦合更多,個人建議是對不一樣的配置項提供不一樣的配置方式:

  1. 若是配置項目是須要讓使用者來配置的,特別是和環境相關的,那麼最好使用配置方式來配置,好比開放的端口、內存、線程數配置,不過要注意:
    1. 全部配置項目須要有默認值,若是找不到配置使用默認值,若是配置不合理使用默認值(你不會但願使用你框架的人把框架內部的線程池的min設置爲999999,或定時器的間隔設置爲0毫秒吧?)
    2. 框架啓動的時候檢測全部配置,若是不合理給予提示,大多人只會在啓動的時候看一下日誌,使用的時候根本就無論
    3. 不知道你們對於配置文件的格式傾向於XML呢仍是JSON呢仍是鍵值對呢?
  2. 對於全部僅在開發時進行的配置,都儘可能不要去使用配置文件,而且讓配置儘可能和它所配置的對象靠在一塊兒:
    1. 若是是對框架總體性進行的設置擴展類型的配置,那就能夠提供代碼方式進行配置,好比咱們要實現的MVC框架的各類IRoute、IViewEngine等,最好能夠提供IConfig接口讓開發人員能夠去實現接口,這樣他們能夠知道有哪些東西能夠配置,代碼就是文檔
    2. 若是是那種對模型、Action進行的配置,好比模型的驗證規則、Filter等一概採用註解的方式進行配置
  3. 有的人說使用配置文件進行配置很是靈活,使用代碼方式和註解方式來配置不靈活並且可能有侵入性。我以爲仍是要權衡對待,個人建議是不要把太多框架 內在的東西放在配置文件中,增長使用者的難度(並且不少時候,大多數人只是複製配置爲了完成配置而配置,並非爲了真正的靈活性而去使用配置文件來配置你 的框架,看看網上這麼所SSH配置文件的抄來抄去就知道了)。
  4. 最後,我建議不少太內部的東西對於輕量級的應用型框架能夠不去提供任何配置選項,只須要在某個常量文件中定義便可,讓真正有需求進行二次開發的開發人員去修改,對於一個框架若是一會兒暴露上百個"高級"配置項給使用者,他們會暈眩的。

提供狀態服務

所謂狀態服務就是反映框架內部運做狀態的服務,不少開源服務或系統(Nginx、Mongodb等)都提供了相似的模塊和功能,做爲框架的話我以爲 也有必要提供一些內部信息(主要是配置、數據統計以及內部資源狀態)出來,這樣使用你框架的人能夠在開發的時候或線上運做的時候瞭解框架的運做狀態,咱們 舉兩個例子,對於一個咱們以前提到的Web MVC框架來講,能夠提供這些信息:

  1. 路由配置
  2. 視圖引擎配置
  3. 過濾器配置

對於一個Socket框架來講,有一些不一樣,Socket框架是有狀態的,其狀態服務提供的信息除了當前生效的配置信息以外,更多的是反映當前框架內部一些資源的狀態以及統計數據:

  1. 各類配置(池配置、隊列配置、集羣配置)
  2. Socket相關的統計數據(總打開、總關閉、每秒收發數據、總收發數據、當前打開等等)
  3. 各類池的當前狀態
  4. 各類隊列的當前狀態

狀態服務能夠如下面幾種形式來提供:

  1. 代碼方式,好比若是開發人員實現了IXXXStateAware接口的話,就能夠爲它的實現類來推送一些信息,也能夠直接在框架中設立一個StateCenter來公開框架全部的狀態信息
  2. 自動日誌方式,好比若是在配置中開啓了stateLoggingInterval=60s的選項,咱們的框架就會自動一分鐘一次輸出日誌,顯示框架內部的狀態
  3. 接口方式,好比開放一個Restful的接口或額外監聽一個端口來提供狀態服務,方便使用者能夠拿原始的數據和其它監控平臺進行整合
  4. 內部外部工具方式
    1. 好比咱們能夠直接爲框架提供一個專門的頁面(/_route)來呈現路由的配置(甚至咱們能夠在這個頁面上讓開發人員能夠直接輸入地址來測試路由的匹配狀況,狀態服務不必定只能看),這樣在開發和測試的時候能夠更方便調試
    2. 咱們也能夠爲框架提供一個專有工具來查看框架的狀態信息(固然,這個工具其實可能就是鏈接框架的某個網絡服務來獲取數據),這樣即便框架在多個機器中使用,咱們可能也只有一個監控工具便可

若是沒有狀態服務,那麼在運行的時候框架就是一個黑盒,反之若是狀態服務足夠詳細的話,能夠方便咱們排查一些功能或性能問題。不過要注意的一點是, 狀體服務可能會下降框架的性能,咱們可能須要對狀態服務也進行一次壓測,排除狀態服務中損耗性能的地方(有些數據的收集會意想不到得損耗性能)。

檢查線程安全

框架對多線程環境支持的是否好,是框架質量的一個重要的評估標準,每每能夠看到甚至有一些成熟的框架也會有多線程問題。這裏涉及幾個方面:

1,你沒法預料框架的使用者會怎麼樣去實例化和保存你的API的入口類,若是你的入口類被用成爲了一個單例,在併發調用的狀況下會不會有單線程問題?

這是一個老話題,以前已經說過不少次,你在設計框架的時候內心若是把一個類定位成了單例的類但卻沒有提供單例模式,你是沒法要求使用者來幫你實現單 例的。這其中涉及的不只僅是多線程問題,可能還有性能問題。好比見過某分佈式緩存的客戶端的CacheClient在文檔中要求使用者針對一個緩存集羣保 持一個CacheClient的單例(由於其中有了鏈接池),可是用的人仍是每一次都實例化了一個CacheClient出來,幾小時後就會產生幾萬個半 死的Socket致使網絡奔潰。又見過某類庫的入口工廠的代碼註釋中寫了要求使用的人把XXXFactory做爲單例來使用(由於其中緩存了大量數據), 可是用的人就沒有注意到這個註釋,每一次都實例化了一個XXXFactory,形成GC的崩潰。因此我以爲做爲框架的設計者開發人員,最好仍是把框架的最 佳實踐直接作到API中,使得使用者不可能出錯(以前說過一句話,再重複一次,好的框架不會讓使用的人犯錯)。你可能會說對於CacheClient的例 子,不可能作成單例的,由於個人程序可能須要用到多個緩存的集羣,換個思路,咱們徹底能夠在封裝一層,經過一個CacheClientCreator之類 的類來管理多個單例的CacheClient。即便在某些極端的狀況下,你不能只提供一條路給使用者去走,也須要在框架內作一些檢測機制,及時提醒使用者 "咱們發現您這樣使用了框架,這可能會產生問題,你本意是否打算那樣作呢?"

2,若是你的入口類原本就是單例的,那麼你是類中是否持有共享資源,你的API在併發的狀況下被調用是否能夠確保這些資源的線程安全?在解決多線程問題的時候每每有幾個難點:

  1. 百密難有一疏,你很難想到這段代碼會有人這樣去併發調用。好比某init()方法,某config()方法,你老是假設使用者會調用而且僅調用一次,但事實不必定這樣,有的時候調用者本身也不清楚個人容器會調用我這段代碼多少次。
  2. 好吧,解決多線程問題各類煩躁,那就對各類涉及到共享資源的方法所有加鎖。對方法進行粗獷(粒度)的鎖可能會致使性能急劇降低甚至是死鎖問題。
  3. 自覺得使用了優雅的無鎖代碼或併發容器但卻達不到目的。咱們每每在大量使用了併發集合心中暗自竊喜解決了多線程問題的同時又達到了極佳的性能,但 你覺得這樣是解決了線程安全問題但其實根本就沒有,咱們不能假設A和B都方法是線程安全的,但對A和B方法調用的整個代碼段是線程安全的。

對於多線程問題,我沒有好的解決辦法,不過下面的幾條我以爲能夠嘗試:

  1. 須要很是仔細的過一遍代碼,把涉及到共享資源的地方,以及相關的方法和類列出來,不要去假設什麼,只要API暴露出去了則假設它可能被併發調用。共享資源不必定是靜態資源,哪怕資源是非靜態的,在併發環境下對相同對象的資源進行操做也可能產生問題。
  2. 通常而言對於公開的API,做爲框架的設計者咱們須要確保全部的靜態方法(或但單例類的實例方法)是線程安全的,對於實例方法咱們能夠不這麼作(由於性能緣由),可是須要在註釋中明確提示使用者方法的非線程安全,若是須要併發調用請自行處理線程安全問題。
  3. 能夠看看是否有可能讓這些資源(字段)變爲方法內的局部變量,有的時候咱們並非真正的須要類持有一個字段,只是由於多個方法要使用相同的東西,隨手一寫罷了。
  4. 對於使用頻率低的一些方法相關的一些資源沒有必要使用併發容器,直接採用粗狂的方式進行資源加鎖甚至是方法級別加鎖,先確保沒有線程安全,若是之後作壓測出現性能問題再來解決。
  5. 對於使用頻率高的一些方法相關的一些資源可使用併發容器,但須要仔細思考一下代碼是否會存在線程安全問題,必要的話爲代碼設計一些多線程環境的單元測試去驗證。

性能測試和優化

以前也提到過,你不會預測到你的項目會在怎麼樣的訪問量下使用,咱們不但願框架和同類的框架相比有明顯的性能差距(若是你作的是一個ORM框架或RPC框架,這個工做就是必不可少的),因此在框架基本完成後咱們須要作Benchmark:

  1. 肯定幾個測試用例,儘可能覆蓋主流程和一些重要擴展
  2. 找幾個主流的同類型框架,實現相同的測試用例,實現到時候要單純一點,儘可能不要再依賴其它外部框架
  3. 爲這些框架和本身的框架,使用壓力測試工具在相同的環境和平臺來跑這些測試用例,使用圖表繪製在不一樣的壓力下的執行時間(以及內存和CPU等主要資源的消耗狀況)
  4. 若是出現明顯的差距則用性能分析工具進行排查和優化,好比:
    1. 優化框架內的線程安全的實現方式
    2. 爲框架內的代碼作一些緩存(緩存反射獲得的元數據等等)
    3. 減小調用層次
    4. 這些調整可能會打破原來的主線流程或讓代碼變得難以理解,須要留下相關注釋
  5. 不斷重壓力測試和優化的過程,每次嘗試優化5%~20%的性能,雖然越到後來可能會越難,若是發現實在沒法優化的話(性能分析工具顯示性能的分佈已經很均勻了),能夠看一下其它框架對於這部分工做實現的代碼邏輯

封裝和擴展

我的以爲一個框架若是隻是能用那是第一個層次,能很方便的進行擴展或二次開發那是另一個層次,若是咱們龍骨階段的工做作的足夠好,框架是一個立體飽滿的框架,那麼這部分的工做量就會小不少,不然咱們須要對框架進行很多的重構以即可以達到這個層次。

  1. 咱們須要縱覽一下框架的全部類型,看看有哪些類型咱們是打算提供開發人員進行加強、擴展或替換的,對這些類型進行響應的結構調整。
    1. 好比但願被加強,則須要從繼承的角度來考慮
    2. 好比但願被擴展,則須要從Provider的角度來考慮
    3. 好比但願被替換,則須要在配置中提供組件的替換
  2. 咱們須要再爲這些類型進行精細化的調整:
    1. 檢查是否該封閉的封閉了,該開放的開放了
    2. 加強擴展或替換是否會帶來反作用
    3. 對於新來的外來類型,接收和使用的時候作足夠的檢查
    4. 相關日誌的完善

重構仍是重構

光是重構這個事情其實就能夠說一本書了,其實我有一點代碼的潔癖,這裏列一些我本身寫代碼的時候注重的地方:

  1. 格式:每次提交代碼的時候使用IDE來格式化你的代碼和引用(固然,實現可能須要配置IDE爲你喜歡的代碼風格)
  2. 命名:保持整個類和接口命名統一,各類er,Provider、Creator、Initializer、Invoker、Selector表明 的是一件事情,不要使用漢語拼音命名,若是英文不夠好的話多查一下字典,有的時候我甚至會由於一個命名去閱讀一些源代碼看看老外是怎麼命名這個對象或這個 方法的
  3. 訪問控制修飾符:這是一個很是難作好的細節,由於有太多的地方有訪問控制修飾符,到底是給予什麼級別的修飾符每每又取決於框架的擴展。能夠在一開 始的時候給儘可能小的權限,在必要的時候慢慢提高,好比對於方法除了必定要給public的地方(好比公共API或實現接口),儘可能都給private,在 有繼承層次關係的時候去給到protected,對於類能夠都給默認包/程序集權限,產生編譯錯誤的時候再去給到public
  4. 屬性/getter、setter:對於非POJO類字段的公開也要仔細想一下, 是否有必要有setter,由於一旦外部能夠來設置類的某個內部字段,那麼不只僅可能改變了類的內部狀態,你還要考慮的是怎麼處理這種改變,是否是有線程 安全問題等等,甚至要考慮是否有必要開放getter,是否應該把類內部的信息公開給外部
  5. 方法:思考每個方法在當前的類中存在是否合理,這是否屬於當前類應該作的事情,方法是否作了太多事情太少事情
  6. 參數:須要思考,對於調用每個方法的參數,應該是傳給方法,仍是讓方法本身去獲取;應該傳多個參數,仍是封裝一個上下文給到方法
  7. 常量:儘可能用枚舉或靜態字符串來代替框架使用到的一些常量或幻數,須要爲常量進行一個分類不能一股腦堆在一個常量類Consts中

除了上面說的一些問題,我以爲對於重構,最重要的一句話就是:不要讓同一段代碼出現兩遍,主要圍繞這個原則進行重構每每就會解決不少設計問題,要實現這個目標可能須要:

  1. 幹差很少活的類使用繼承來避免代碼重複(提煉超類),使用模版方法來把差別留給子類實現
  2. 構造方法能夠層次化調用,主構造方法只要一個就能夠了,不要在構造方法中實現太多邏輯
  3. 若是方法的代碼有重複能夠考慮對方法提取出更小的公共方法來調用(提煉方法),也能夠考慮使用Lambda表達式進行更小粒度重複代碼的提取(提煉邏輯)
  4. 可使用IDE或一些代碼分析工具來分析重複代碼,若是你能想盡一切辦法來避免這些重複的話,代碼質量能夠提升一個層次

其實也不必定是在重構的時候再去處理上面全部的問題,若是在寫代碼的時候都帶着這些意識來寫的話那麼重構的負擔就會小一點(不過寫代碼思想的負擔比 較大,須要同時考慮封裝問題、優雅問題、日誌異常問題、多線程問題等等,因此寫一套能用的代碼和寫一套好的代碼其實不是一回事情)。

項目文檔

若是要別人來使用你的框架,除了示例項目來講提供和維護一份項目文檔是頗有必要的,我建議文檔分爲這幾個部分:

  1. 特性 Features:
    1. 至關於項目的一個宣傳手冊,讓別人能被你項目的亮點所吸引
    2. 每個特性能夠是一句話來介紹
  2. 新手入門 Get started:
    1. 介紹框架的基本定位和做用
    2. 從下載開始,經過一步一步的方式讓用戶瞭解怎麼把框架用起來
    3. 整個文檔的閱讀時間在10分鐘之內
  3. 新手教程 Tutorials:
    1. 提供5~10篇文章站在使用者的角度來介紹項目的主要功能點
    2. 仍是經過一步一步的方式,教你們使用框架完成一個小項目(好比CRUD)
    3. 介紹框架使用的最佳實踐
    4. 整個文檔的閱讀時間在8小時內
  4. 手冊 Manual:
    1. 介紹項目的定位和理念
    2. 詳細介紹項目的每個功能點,能夠站在框架設計者的角度多介紹一些理念
    3. 詳細介紹項目的每個配置,以及默認配置和典型配置
    4. 詳細介紹項目的每個擴展點和替換點

文檔最好不是帶格式的,方便之後適配各類文檔生成器和開源網站

開源

開源的好處是有不少人能夠看到你的代碼幫助你改進,你的框架也可能會在更多的複雜環境下使用,框架的發展會較快框架的代碼質量也會有很大的提高。

要把框架進行開源,除了上面的各類工做以外可能還有一些額外的工做須要作:

  1. 選擇一個合適的License,而且檢測本身選擇的License與使用到的類庫的License是否兼容,在代碼頭的地方標記上License。
  2. 要確保每個人均可以在本身的環境中能夠構建你的代碼,儘可能使用Maven等你們熟悉的構建工具來管理依賴和構建。
  3. 選擇諸如Github等平臺來管理源代碼,並以良好的格式上傳你的文檔,有條件的話對示例子網站進行部署。
  4. 若是你但願你的代碼讓更多的人一塊兒來參與開發,那麼須要制定和公開一些規範,好比風格、命名、提交流程、測試規範、質量要求等等。
  5. 開源後時刻對項目進行關注,對各類反饋和整合請求進行及時的反饋,畢竟開源是讓別人來幫你一塊兒改進代碼,不是單純讓別人來學習你的代碼也不是讓別人來幫你寫代碼。

看到這裏你可能相信我一開始的話了吧,框架可使用到完善能夠商用差距仍是很大的,並且還要確保在迭代的過程當中框架不能偏離開始的初衷不能有很大的性能問題出現,任重道遠。

做者: lovecindywang
轉自:http://www.cnblogs.com/lovecindywang/p/4447739.html
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。
相關文章
相關標籤/搜索