1. 相容性的重要性與反面教材
Java 與c#的相容性走很好,win也很關注相容性...
反面教材啊,也有啊..python3, cocos2d-js v3.x的問題
一旦上述提到的5個API中的任何一個發生變化,可能會給他們帶來巨大的代價,使用者需要排查所有調用的代碼,需要更改一些協定,需要調整所有與之相關的部分,這些工作對他們來說都是額外的,在預期之外的。如果辛辛苦苦完成這些以後,還在測試過程中發現了相關的bug,那對使用者的打擊就更大了。如果API經常發生變化,使用者就會失去對這段程式的信任,他們會更傾向自己獲得源代碼以後,按照自己的需求進行修改,自行維護一個内部的API比調用一個不斷發生變化的外部API要容易接受的多,雖然這樣做和我們協同開發、子產品化開發的初衷是完全相悖的
保護使用者在API上的已有工作
使用者過去在調用API、基于API開發所做的工作,這樣才能給使用者帶來價值的同時,不破壞他們過去的勞動成果
2. 提升相容性的原則
2.1. What 與how 分離
例如,ui ,使用dsl html5 css來定義 ui ,不要使用native winform式的3gl語言
後端, 資料操作使用linq,sql ,不要自己寫一瓦代碼,麻煩的.
别的例如遊戲,使用接口模式..定義一些api當dsl ,,使用實作來不同的實作..
例如cocos的定義場景,很麻煩的
// add bg
// var size = cc.director.getWinSize();
this.bgSprite = new cc.Sprite(res.BackGround_png);
this.bgSprite.attr({
x: size.width / 2,
y: size.height / 2,
});
this.addChild(this.bgSprite, 0);
使用dsl html5 走容易的,還有标準的dw ide支援..可視化的ui設計.很友善的實作後端重構,不影響使用者..
<div style=”background:url(xxxxx.jpg); x:0; y:0 ”> </div>
後端解析這個html dsl 定義,生成canvas對象走ok...
2.2. 老人老辦法,新人新辦法,隻新增,少修改,莫删除
2.3. 計劃趕不上變化,永遠api修改也不可能整齊劃一,反而帶來不相容的風險
3. 把握API的生命周期andAPI分級
· 為API分級:内部使用;二次開發使用;開發或試用中;穩定;棄用API。避免API被濫用的同時,我們可以通過調整API的級别,來擴大其影響力,也能更優雅的結束一個API的生命周期。
4. 對相容性保持友好的api設計方法
4.1. 細粒度的方法
方法api功能越細,越任意單獨更新方法版本
4.2. Ioc容器動态配置
相容性的神器。。
4.3. 把你的method()視為全局global的,確定每一個方法都不重名盡可能。。不要幻想有子產品命名空間等,這也是為了友善使用者查詢。。
一般使用事件做uuid字尾,基本可以確定不同。
4.4. Api版本管理與 細粒度的方法Api版本管理
可以直接在方法簽名增加 xxx_v2()這樣的實作版本方法即可。
粗粒度的api版本管理使用ioc組合不同的細粒度api
4.5. 使用ioc方法。 容器正是個好東西啊
5. 保持api相容性的新版本更新方法
5.1. 不要重構以前的api内部具體實作,以達到無縫更新的效果
除非絕對必要,不要重構以前的api具體實作,而是新增一個。。。重構以前的api難免增加bug,帶來不穩定。。 當然api接口的話,可以保留。。
就像java,很多更新都是重構以前的實作,可以帶來更高的性能等,但風險較大,對能力要求較高。。。普通公司,還是新增為主。。這樣新版本app可以使用新api,就版本app任然使用舊api即可。。
接口函數一旦釋出就不能改了,要保持相容性,拼寫錯誤也不能改了,是以要仔細檢查拼寫,否則會被同行嘲笑很多年。
著名悲劇:unix 的 creat
5.2. 不要向已經釋出的接口裡添加成員;建立新的接口來避免版本問題
5.3. 建立新的api應該使用什麼标準???
簡單的,使用世界流行的,标準化的标準走ok..
例如ui方面,使用h5标準,不足了補充使用wpf,,優點是資料多啊,你都可以不需要寫api文檔了,直接使用這個标準的資料走ok,資料足夠..
後端語言api 了??? 使用流行的java ,js ,可以補充c#風格拉.. C++ ,obj-c不推薦..
5.4. 增加功能 增加新api 而不是 修改舊的api
最好是增加新的api。。這樣不用調整老的api..添加測試工作...
當然一些很小的的調整可以直接調整老的api
一些必須修改老api的,可以變成api0模式,在新的api裡面調用即可。修改bug模式。。
新api的命名可以采用 xxxV2 的模式這樣就可以相容老api。。
5.5. 修改api (那就是盡可能不要修改api,使用增加來代替)
5.6. 增加參數 (可以通過可變參數json來擴充參數)
增加參數也可以通過threadlocal方式來實作,這樣就不用改動原來的方法簽名
5.7. 增加傳回值而原來api是void。。可以直接增加傳回值,或者傳回在某個成員變量上
5.8. Threadlocal
它還有一些類似的方式用來使用,就是在架構級别有很多動态調用,調用過程中需要滿足一些協定,雖然協定我們會盡量的通用,而很多擴充的參數在定義協 議時是不容易考慮完全的以及版本也是随時在更新的,但是在架構擴充時也需要滿足接口的通用性和向下相容,而一些擴充的内容我們就需要 ThreadLocal來做友善簡單的支援。
簡單來說,ThreadLocal是将一些複雜的系統擴充變成了簡單定義,使得相關參數牽連的部分變得非常容易,以下是我們例子說明:
5.9. 避免極端的意見在設計API的時候,一定要避免任何極端的意見,
尤其是以下幾點:必須漂亮(API一定要漂亮嗎?前文已經說過了) API必須被正确地使用(使用者很難了解如何正确的使用API,API的設計者要充分考慮API被誤用的情況:如果一個API可能會被誤用,那麼它一定會被誤用) 必須簡單(我們總會面臨複雜的需求,能兩者兼顧的API是更好的API) 必須高性能(性能可以通過其他手段優化,不應該影響API的設計) 必須絕對相容(盡管本文一直提到如何保證相容,但是我們仍然要意識到,一些極少情況下會遇到的不相容是可以容忍的) 一些具體的實施方案在一個API不可避免要消亡或者改變的時候,我們應該接受并且面對這個事實,下面列舉了幾種保證相容性的前提下,對API進行調整的辦法:将API标記為棄用,重建立立一個新的API。如果一個API不可避免要被消亡,這是唯一的辦法。 為其添加額外的參數或者參數選項來實作功能添加 将現有API拆成兩部分,提供一個精簡的核心API,過去的API通過封裝核心API上實作。這通常用于解決使用者需要一個代碼精簡的版本時。
6. 如何廢棄api (使用depre辨別,千萬不要删除
在一個API不可避免要消亡或者改變的時候,我們應該接受并且面對這個事實,下面列舉了幾種保證相容性的前提下,對API進行調整的辦法:
· 将API标記為棄用,重建立立一個新的API。如果一個API不可避免要被消亡,這是唯一的辦法。
· 為其添加額外的參數或者參數選項來實作功能添加
· 将現有API拆成兩部分,提供一個精簡的核心API,過去的API通過封裝核心API上實作。這通常用于解決使用者需要一個代碼精簡的版本時。
· 在現有的API基礎上進行封裝,提供一個功能更豐富的包或者類
7. 我們的app現在使用v1.0版api,如何慢慢切換到2.0呢
每一個api下面有許多方法。。比如m1 m2
使用ioc方法。 先搞個api2.0 ,預設加載全部1.0的方法。。然後針對需要新加或者修改的方法,做2.0版本,然後在ioc裡面配置,讓api2.0使用那幾個新版本方法。其他的方法任然可以使用就版本,即是可以任意組合細粒度的方法啦。。
Ref參考資料
如何做到API相容 - 百度技術部落格 - 51CTO技術部落格.html
作者:: 綽号:老哇的爪子