增加程式碼的通用性-解析配置檔案

rexkentzheng發表於2018-11-07

時間:2018年11月02日
比方說有這樣一堆資料:

arr: [{
  id: '1',
  type: 'a',
  arr: [1, 2, 3, 4]
}, {
  id: '2',
  type: 'b',
  arr: [1, 2, 3, 4, 5]
}]
複製程式碼

集合裡面每個元素都有兩個屬性,一個是type,一個是arrarr是一個陣列。
需求是先判斷屬性,不同屬性對arr的長度有著不同的需求。這裡我們規定type若是‘a’,arr的長度最多為4。type若是‘b’,arr的長度最多為6;兩者的報錯內容也並不相同。
我的本意是迴圈目標陣列,之後先判斷是否符合type,再判斷arr是否符合條件,將不符合條件元素的id存到一個陣列中,最後展示出來:

aError = [];
bError = [];
_.each(arr, (op) => {
  if (op.type === 'a') {
    if (op.arr.length > 4) {
      aError.push(op.id);
    }
  }
  if (op.type === 'b') {
    if (op.arr.length > 6) {
      bError.push(op.id);
    }
  }
})
if (aError) {
  const errMsg = `a的報錯提示:${aError.join(',')}`;
}
if (bError) {
  const errMsg = `b的報錯提示:${bError.join(',')}`;
}
複製程式碼

寫完之後自我感覺還是不錯的,看上去挺清楚的,邏輯什麼的也很簡單,如果還有其他的再增加就好了。
問題是寫完之後和同事討論了一下,覺得程式碼的複用性太差,如果有新的條件會增加更多的程式碼,這種重複造輪子的操作感覺不是很好。所以商討之後我們決定將條件寫成一個配置檔案,通過讀取配置檔案來解析條件,再進行判斷。
那麼配置檔案需要什麼內容呢?主要有三部分,type型別、最大arr數量,還有報錯資訊,所以我們決定了配置檔案的格式:

limitRule = {
  a: {
    max: '4',
    errMsg: 'content'
  },
  b: {
    max: '6',
    errMsg: 'content'
  }
}
複製程式碼

直接把type型別當做了配置元素的key,減少了一個屬性。之後我們就要開始迴圈配置檔案了。

let limitIds = {};
const limitErrMsg = [];
_.each(arr, (op) => {
  if (_.keys(limitRule).includes(op.type)) { //獲取到配置檔案中所有的型別,之後判斷當前型別是否在配置檔案中
    if (op.arr.length > limitRule[op.type].max) {
      if (limitIds[op.type]) {
        limitIds[op.type].push(op.id);  //如果已經有這個type就直接push
      } else {
        limitIds[op.type] = [op.id];  //如果沒有這個type就新建陣列
      }
    }
  }
})
複製程式碼

這裡的_.keylodash中獲取物件key的方法。先判斷下當前元素的type是否在配置檔案中,如果在再進行下一步判斷,判斷當前元素陣列的長度是不是大於配置檔案中當前配置的max值。若是大於,再將當前元素的id放到limitIds物件中,如果limitIds中沒有當前型別的資料,則新建一個,若是有則push進去。如此,我們得到的limitIds應該是這樣的:

{
  a:[1, 3, 7],
  b: [7, 9, 10]
}
複製程式碼

接下來我們處理下limitIds,得到報錯資訊:

_.mapObject(limitIds, (value, key) => {
  if (value) {
    limitErrMsg.push(`${limitRule[key].errMsg}${value.join(',')}`)
  }
})
複製程式碼

如此我們就將所有的報錯資訊放到limitErrMsg中了,之後輸出即可。整體方法是這樣的:

//  配置檔案
limitRule = {
  a: {
    max: '4',
    errMsg: 'content'
  },
  b: {
    max: '6',
    errMsg: 'content'
  }
};
//  新建儲存資訊的變數
let limitIds = {};
const limitErrMsg = [];
//  處理資料
_.each(arr, (op) => {
  if (_.keys(limitRule).includes(op.type)) { //獲取到配置檔案中所有的型別,之後判斷當前型別是否在配置檔案中
    if (op.arr.length > limitRule[op.type].max) {
      if (limitIds[op.type]) {
        limitIds[op.type].push(op.id);  //如果已經有這個type就直接push
      } else {
        limitIds[op.type] = [op.id];  //如果沒有這個type就新建陣列
      }
    }
  }
})
//  得到錯誤資訊
_.mapObject(limitIds, (value, key) => {
  if (value) {
    limitErrMsg.push(`${limitRule[key].errMsg}${value.join(',')}`)
  }
})
複製程式碼

如此就將不同的判斷條件整合成了一個配置檔案,之後若是還有類似的配置直接修改配置檔案即可,簡直不要太方便。

相關文章