[轉(zhuǎn)載] 接口的冪等性

絕大部分網(wǎng)絡(luò)上對冪等性的解釋類似于:

"冪等性是指重復(fù)使用同樣的參數(shù)調(diào)用同一方法時總能獲得同樣的結(jié)果。比如對同一資源的GET請求訪問結(jié)果都是一樣的。"

我認為這種解釋是非常錯誤的,冪等性強調(diào)的是外界通過接口對系統(tǒng)內(nèi)部的影響, 外界怎么看系統(tǒng)和冪等性沒有關(guān)系。就上面這種解釋, System.getCPULoad(),這兩次調(diào)用返回能一樣嗎? 但因為是只讀接口,對系統(tǒng)內(nèi)部狀態(tài)沒有影響,所以這個函數(shù)還是冪等性的。

首先了解一下什么是冪等性,如果你沒有興趣可以直接跳過這段代數(shù)概念解釋 :)
冪等(idempotence)是來自于高等代數(shù)中的概念。
定義如下(加入了自己理解):

  • 單目運算, x為某集合內(nèi)的任意數(shù), f為運算子如果滿足f(x)=f(f(x)), 那么我們稱f運算為具有冪等性(idempotent)。
    比如在實數(shù)集中,絕對值運算就是一個例子:
abs(a)=abs(abs(a))
  • 雙目運算,x為某集合內(nèi)的任意數(shù), f為運算子如果滿足f(x,x)=x, f運算的前提是兩個參數(shù)都同為x, 那么我們也稱f運算為具有冪等性。
    比如在實數(shù)集中,求兩個數(shù)的最大值的函數(shù):
max(x,x) = x

還有布爾代數(shù)中,邏輯運算 "與", "或" 也都是冪等運算, 因為他們符合:

AND(0,0) = 0
AND(1,1) = 1
OR(0,0) = 0
OR(1,1) = 1

在將冪等性應(yīng)用到軟件開發(fā)中,需要一些更深的理解。我的理解如下:

數(shù)學處理的是運算和數(shù)值,程序開發(fā)中往往處理的是對象和函數(shù). 但是我們不能簡單地理解為數(shù)學冪等中的運算就是函數(shù),而數(shù)值就是對象??!

比如有 Person 對象有兩個屬性 weight 和 age ,但是所有的 function 只能對其中一個屬性操作。所以從這個層面我們可以理解為:函數(shù)只對該函數(shù)所操作的對象某個屬性具有冪等性,而不是說對整個對象有運算冪等性。

Person {
 private int weight;
 private int age;
 //是冪等函數(shù)
 public void setAge(int v){
     this.age = v; 
 }
 //不是冪等函數(shù)
 public void increaseAge(){
     this.age++;
 } 
 //是冪等函數(shù)
 public void setWeight(int v){
     this.weight=v+10;//故意加10斤!!
 }
}

還有一點必須要澄清的是:

冪等性所表達的概念關(guān)注的是數(shù)學層面的運算和數(shù)值,并沒有提及到數(shù)值的安全性問題。

比如上面的Person的setAge函數(shù),有兩種case不是冪等性所關(guān)心的,但程序開發(fā)卻又必須要關(guān)心的:

  1. 兩個線程同時調(diào)用
  2. 因為age從業(yè)務(wù)上講不可能遞減, 如果前一次調(diào)用設(shè)置是30歲,后一次調(diào)用變成了10歲或是更離譜的 -1 歲

所以RESTful設(shè)計中將冪等性和安全性是作為兩個不同的指標來衡量POST/PUT/GET/DELETE 操作的:

重要方法 安全? 冪等?
GET
DELETE
PUT
POST

冪等性是系統(tǒng)的接口對外一種承諾(而不是實現(xiàn)), 承諾只要調(diào)用接口成功, 外部多次調(diào)用對系統(tǒng)的影響是一致的. 聲明為冪等的接口會認為外部調(diào)用失敗是常態(tài),并且失敗之后必然會有重試。

就象cache有cache基本實現(xiàn)范式一樣, 冪等也有自己的固定外部調(diào)用范式。
cache實現(xiàn)范式:

value getValue(key){
    value = getValueFromCache(key);

    if( value == null ){
        value = readFromPersistence(key);
        saveValueIntoCache(key,value);
    }

    return value;
}

冪等外部調(diào)用范式:

client.age = 30;
while(一些退出條件) {
    try {
        if(socket.setPersonAge(person,client.age) == FAILED) {
// 處理沖突問題: 因為age只可能越來越大,所以將client的age更新為server端更大的age
            int newAge = socket.getPersonAge();
            if(newAge>30) {
                client.age = newAge;
                break;
            } else {
            //無法進行沖突解決,再次嘗試
            }
      } else 
            return; 
  } catch(Exception) { 
        //發(fā)生網(wǎng)絡(luò)異常, 再次嘗試 
  }
}

** 冪等接口的內(nèi)部實現(xiàn)需要有對內(nèi)保護機制,一般情況是用類似于樂觀鎖的版本機制.版本重點是體現(xiàn)時間的先后。**

原創(chuàng)鏈接:http://www.smithfox.com/?e=16 轉(zhuǎn)載請保留此聲明, 謝謝

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 絕大部分網(wǎng)絡(luò)上對冪等性的解釋類似于:"冪等性是指重復(fù)使用同樣的參數(shù)調(diào)用同一方法時總能獲得同樣的結(jié)果。比如對同一資源...
    wyatt_plus閱讀 6,135評論 0 4
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,652評論 18 399
  • 1.冪等性定義 1.1 數(shù)學定義 在數(shù)學里,冪等有兩種主要的定義: 在某二元運算下,冪等元素是指被自己重復(fù)運算(或...
    王帥199207閱讀 5,037評論 0 152
  • 笹垣說,她認為這是可以奪取靈魂的方式。 這指的是“強暴女性”。 對藤村施暴,對江利子施暴,對美佳施暴。而三者不同的...
    唐澤荼荼閱讀 2,176評論 0 0
  • 這次活動分享人是張期鵬老師,開始先說了說自己的經(jīng)歷,他做過小學和初中教師,后來回憶過去的人生,感覺做教師的時光是最...
    蘇步哲閱讀 658評論 0 0

友情鏈接更多精彩內(nèi)容