天天看點

Atitit Atitit.軟體相容性原理----------API相容 Qa7

 ​

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

作者:: 綽号:老哇的爪子