防御式編程

編寫優(yōu)秀的代碼

  1. 代碼是程序可識別的代碼
  2. 代碼是程序員可識別的代碼

防御性編程

防御性編程(Defensive programming)是防御式設(shè)計的一種具體體現(xiàn)厉熟,它是為了保證,對程序的不可預(yù)見的使用白翻,不會造成程序功能上的損壞绢片。它可以被看作是為了減少或消除墨菲定律效力的想法。防御式編程主要用于可能被濫用巢株,惡作劇或無意地造成災(zāi)難性影響的程序上熙涤。---百度百科

為什么要進行防御性編程

防御性編程是為了讓我寫出可維護以及更少的bug的一種編程方式,它可能完全讓我們寫出無bug的應(yīng)用程序所以我們在編寫代碼的時候要始終保持一顆警惕之心那槽。通常的編碼方式是下面這種:

  • 編碼 -> 測試 -> 編碼 -> 測試-> .......
    這種方式去編寫和調(diào)試代碼等舔,如果我們使用防御性編程編寫代碼之后基本上就可以使用下面這種方式進行

  • 編碼 -> 測試 -> 測試 -> .....

如何減少bug


// 程序出Bug了?
//    ∩∩
//  』胖病(′?ω?)
//   _| ?/(___
// 〉咏健/ └-(___/
//   ̄ ̄ ̄ ̄ ̄ ̄ ̄
// 算了反正不是我寫的
//    ?⌒/ヽ-只锭、_
// ≡憾/?_/____ /
// 『硖堋 ̄ ̄ ̄ ̄ ̄ ̄ ̄
// 萬一是我寫的呢
//    ∩∩
//  ∽莨恕(′?ω?)
//   _| ?/(___
//  / └-(___/
// 》蠼谩 ̄ ̄ ̄ ̄ ̄ ̄ ̄
// 算了反正改了一個又出三個
//    ?⌒/ヽ-汉额、_
//  /?_/____ /
// ≡趺! ̄ ̄ ̄ ̄ ̄ ̄ ̄

一個應(yīng)用程序一般是處理外部輸入妓灌,然后將處理結(jié)果輸出。一般在這個過程中有以下幾個地方會產(chǎn)生bug

  • 外部輸入 -> 程序處理 -> 輸出
  1. 外部輸入

    不要相信任何輸入祥山,進行入?yún)z測

  2. 程序處理

    注意拋出的異常掉伏,以及邏輯分支處理

  3. 程序輸出

    異常時的輸出,成功和失敗時的輸出

外部輸入

比如服務(wù)器返回的數(shù)據(jù)岖免,以及函數(shù)的一些入?yún)ⅰN覀儜?yīng)該建立和服務(wù)器返回數(shù)據(jù)類型一樣的接口為了接下來的編碼工作更容易的進行话侧。


{
    "code": 1,
    "data": {
        "count": 3,
        "result": [{
            "gId": "49",
            "iconUrl": "http:\/\/pic.cdn.sunmi.com\/IMG\/5a715de5d6162.png",
            "goods_title": "銀豹零售版",
            "goods_describe": "全場景滿足中小零售門店經(jīng)營需求",
            "goods_unit": "3",
            "goods_spec": "標(biāo)準(zhǔn)版",
            "sId": "218",
            "goods_price": "180.00",
            "goods_type": "1",
            "num": "1",
            "subTotal": 180,
            "cart_id": "1615",
            "unit": "0",
            "begin_num": "1"
        }],
        "total": 14716,
        "number": 15
    },
    "msg": ""
}

我們的接口應(yīng)該是這樣的


interface GoodItem {
  gId: string,
  iconUrl: string,
  goodsTitle: string,
  goodsDescribe: string,
  goodsUnit: string,
  goodsSpec: string,
  sId: string,
  goodsPrice: string,
  goodsType: string,
  num: string,
  subTotal: number,
  cartId: string,
  unit: string,
  beginNum: string
}

interface CartListResponse {
  code: number,
  result: Array<GoodItem>,
}

編寫一個函數(shù)

編寫一個函數(shù)應(yīng)該注意這幾點

  • 參數(shù)
  • 返回值
  1. 參數(shù)

    對于函數(shù)的入?yún)⑹欠裥枰獧z查瞻鹏,做哪些檢查

    • 類型檢查

      對于js這種弱類型語言進行類型檢查是必須的鹿寨,如果沒有進行類型檢查就會造成bug的產(chǎn)生比如

      function contain(item, array) {
        return array.indexOf(item) !== -1
      }
      

      這樣看起來似乎沒有問題,這是因為這看起來好像是我們這個方法從函數(shù)和參數(shù)的命名上是說我們查 看一個元素是否在數(shù)組中,似乎沒有錯赫悄,但是一般作為一個工具函數(shù)的話,我們肯定要考慮到多種情況就是如果傳入的參數(shù)array是一個null埂淮,或者undefined或者是字符串倔撞,或者是object類型怎么樣,當(dāng)然傳入一個字符串他也是能工作的痪蝇,但是這不是我們創(chuàng)建這個函數(shù)的初衷。

      
      function contain(item, array=[]) {
          return array.indexOf(item) !== -1
      }
      
      

      我們給array默認(rèn)傳一個空數(shù)組那么就可以解決了上面的array為空和undfied等情況趁矾,但是其他類型函數(shù)不能進行工作丙唧。還是會報錯。那么肯定有人會說我創(chuàng)建這個函數(shù)就是讓用戶輸入數(shù)組培漏,但是它輸入其他類型就是不對的胡本。由于js的類型是運行時才能確認(rèn)出來的,所以我們在編寫代碼的時候就應(yīng)該注意侧甫。

      function contain(item, array=[]) {
          if (!_.isArray(array)) {
              return false
          }
          
          return array.indexOf(item) !== -1
      }
      

      當(dāng)然我們可以使用ts在編譯階段就能告訴我們這些錯誤

      
      function contain<T>(item: T, array: Array<T>) {
          return array.indexOf(item) !== -1
      }
      
      
  2. 返回值

    一個函數(shù)的返回值應(yīng)該是確定的披粟,除非這個函數(shù)是非受控的函數(shù)。

    
    function jsonParse(string: string): ?object {
        if (string.length === 0) {
          return null
        }
    
        let object = null
    
    
        try {
          object = JSON.parse(string)
        } catch (error) {
          // 處理錯誤
          console.log(error)
        }
        return object
    

}

```

上面這段代碼是把一個json字符串轉(zhuǎn)換成一個對象惑艇,可能存在解析失敗的情況拇泛。我們看到這個函數(shù)就是一個非受控的函數(shù),有兩種返回值俺叭,空或者有值得情況。這一種返回值我們叫做option value 因為外界使用的過程會進行非空判斷蜈垮。

```js
const people = jsonParse("{"age":4}")
if(people) {
    console.log(people.age)
}

```

如果代碼可以寫成下面的多好啊

```js
const people = jsonParse("{"age":4}")
console.log(people?.age)
```

js可以使用babel插件實現(xiàn)這種可選鏈,以后可能會加到es標(biāo)準(zhǔn)中去课兄。[ts](https://github.com/Microsoft/TypeScript/issues/16)還不支持晨继。其實在js中我們經(jīng)常能遇到這種情況比如要取得某個屬性我們都是 
```
   const data = response && response.result && response.result.data
``` 


一個完整的函數(shù)應(yīng)該是這樣的

```js

function name(params:type) {
  // 條件檢查
  if (condition) {
    return
  }

  // 變量聲明和初始化

  const name = null
  const age = null

  // 邏輯操作數(shù)據(jù)處理

}

```

#### if語句需不需要else

```js

if(condition) {
    // 條件滿足時的情況
} else {
    // 條件不滿足的情況
}

```
如果條件不滿足的情況我們不希望函數(shù)執(zhí)行下去

```
    if(!condition) {
        return
    }
    
    //處理條件滿足時的情況

```

#### switch 語句一定要有defautl

```js
    
    switch (key) {
      case value:
        
        break;
    
      default:
        break;
    }

```

減少變量的聲明

在聲明一個變量的時候應(yīng)該考慮是否需要這個變量搬俊,特別是全局變量.下面有兩個例子大家感覺那個代碼比較容易讀?


    enum PeopleType {
      none = '0',
      man = '1',
      woman = '2'
    }

 function getPeopleType(type:PeopleType) {
    let peopleType = null

    switch (type) {
      case PeopleType.none:
        peopleType = 'none'
        break;
      case PeopleType.man:
        peopleType = 'man'
        break;
      case PeopleType.woman:
        peopleType = 'woman'
        break;
      default:
        peopleType = 'none'
        break;
    }

    return peopleType
  }

    enum PeopleType {
      none = '0',
      man = '1',
      woman = '2'
    }

  function getPeopleType(type:PeopleType) {
    if (type === PeopleType.none) {
      return 'none'
    }

    if (type === PeopleType.man) {
      return 'man'
    }

    if (type === PeopleType.woman) {
      return 'woman'
    }

    return 'none'
  }

面對bug每個人的反應(yīng)不同

首先來看看遇到bug各種程序員是怎么反應(yīng)的:

理性型:這個 bug 能復(fù)現(xiàn)嗎唉擂?
自負(fù)型:這不可能,在我這是好好的腹缩。
經(jīng)驗型:不應(yīng)該空扎,以前怎么沒問題?
幻想型:可能是數(shù)據(jù)有問題转锈。
無辜型:我好幾個星期都沒碰這塊代碼了!
樂觀型:只需要改一行代碼竿痰,不會影響其它程序的砌溺。
實踐型:你重啟一下服務(wù)試試。

---- 來自知乎如何減少bug

總結(jié):

1. 進行code review
2. 編寫UT
3. 良好的編碼習(xí)慣(嚴(yán)謹(jǐn)?shù)倪壿嬎季S)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蟹倾,一起剝皮案震驚了整個濱河市楷力,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌岔留,老刑警劉巖检柬,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件竖配,死亡現(xiàn)場離奇詭異里逆,居然都是意外死亡,警方通過查閱死者的電腦和手機胁镐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門盯漂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人就缆,你說我怎么就攤上這事谒亦。” “怎么了切揭?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵脾还,是天一觀的道長。 經(jīng)常有香客問我嗤谚,道長怔蚌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任椅野,我火速辦了婚禮籍胯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘杖狼。我一直安慰自己,他們只是感情好理朋,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著次舌,像睡著了一般兽愤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上国拇,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天惯殊,我揣著相機與錄音也殖,去河邊找鬼。 笑死忆嗜,一個胖子當(dāng)著我的面吹牛捆毫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播绩卤,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼濒憋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了凛驮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤宏胯,失蹤者是張志新(化名)和其女友劉穎本姥,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體了牛,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年甫窟,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛙婴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡浇衬,死狀恐怖餐济,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情醉冤,我是刑警寧澤篙悯,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站螺捐,受9級特大地震影響矮燎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜漏峰,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望倔喂。 院中可真熱鬧靖苇,春花似錦、人聲如沸贤壁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绰上。三九已至,卻和暖如春蜈块,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爽哎。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工器一, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人产镐。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓踢步,卻偏偏與公主長得像丑掺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子街州,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 防御式編程 在防御式駕駛中要建立這樣一種思維唆缴,那就是你永遠也不能確定另一位司機將要做什么。這樣才能夠確保在其他人做...
    劉碩jessie閱讀 5,415評論 1 49
  • 主要思想: 子程序應(yīng)該不因傳入錯誤數(shù)據(jù)而被破壞艳丛, 哪怕是由其他子程序產(chǎn)生的錯誤數(shù)據(jù)趟紊;換一種說法是, 程序員應(yīng)該承認(rèn)...
    娟子閱讀 2,321評論 0 1
  • 最近業(yè)余時間在閱讀《代碼大全》戴差,閱讀“防御式編程”章節(jié)的時候非常受啟發(fā)铛嘱,自己之前對系統(tǒng)的錯誤處理這塊也確實隨意了袭厂。...
    henry_g閱讀 629評論 0 0
  • 當(dāng)你想要時間上的自由球匕,那你必須努力做到金錢上的自由才行! 當(dāng)你一味地覺得爽航,你把掙的錢給你最至親的人,是在幫助他們減...
    X阿霞閱讀 126評論 0 0
  • 《書都不會讀讥珍,你還想成功》 零散時間比你想象的要多 文/吳曉黎 什么樣的時間可以用來讀書窄瘟?當(dāng)你的答案確定為利用一切...
    吉佳嚦嚦閱讀 236評論 0 1