重構:燒腦判斷大掃除

編寫業務代碼的時候經常會遇到判斷,面對各類業務場景,你知道最優方案嗎?程序員

讓咱們看看基本狀況:es6

初級:if else else if一把梭幹就完事設計模式

中級:switch case、if else、多態、用設計模式包裝數組

高深:清晰全部判斷條件的邊界,用解釋性強且合理的方式app


給各位大佬泡上一杯82年的卡布奇諾,細細品味。函數

代碼初窺

需求:判斷今日上班狀況,當前時間和工做進度做爲條件性能

{
    period:afteroon,// 當前時間:afternoon || night
    workProgress:start,  // 工做進度: start || end
}
複製代碼

if-else

if(period === 'afternoon'){
    上班
}else if(period === 'night' && workProgress !== 'end'){
    加班
}else {
    下班
}
複製代碼

優勢: if else 最爲常見,是全部程序員最熟悉判斷語句,能夠包含複雜條件。ui

缺點: 邏輯過多就會變得很是冗長難以理解。spa

若是不看上班和加班的表達式能快速理解什麼狀態對應的下班嗎設計

switch-case

switch(period){
    case 'afternoon':
       上班
    break;
    case 'night' && workProgress:
       下班
    break;
    case  'night' && workProgress !== 'end':
       加班
    break;
    default:
       肝就完事
    break;
}
複製代碼

優勢: 多種平行條件下更加簡潔直觀,可跳出,性能更優。

缺點: 同條件的邏輯過多就會變得像裹腳布,嵌套以及非同條件的表達式難度大。

條件變得複雜,再加一個狀態(星期,周2、週四固定加班),還能維護嗎

三元運算: 、短路運算 && ||

優勢: 代碼更加的簡潔精煉

缺點: 過於複雜的三元運算語義化不強同時難以維護

period === 'afternoon'? '上班' : (workProgress === 'end'? '下班' : '加班')
複製代碼

同上,條件變得複雜還能維護嗎,同時看懂這串代碼已經須要一點時間了。。。

策略模式/狀態模式 設計模式封裝

優勢: 易於維護,具備必定解釋性,多態

缺點: 代碼量複雜度增長,須要必定抽象能力

const AllState = {
    '上班':onWork,
    '下班':endWork,
    '加班':stillWork,
}
const period = 'night';
const workProgress  = 'start';
 
function onWork() {
    return period === 'afternoon';
}

 function endWork() {
    return period === 'night' && workProgress === 'end';
}

 function stillWork() {
    return period === 'night' && workProgress === 'start';
}

function getWorkState() {
    let state = '肝就對了';
    Object.keys(AllState).some((result) =>{
        if(AllState[result]()){
            state = result;
            return true;
        };
    });
    console.log(state);
    return state;
}

const workState = getWorkState();
複製代碼

增長了代碼可維護性和可讀性,支持多態,可是也增長了代碼量和時間成本

語義化

你是一個新入職的員工,你的老大拍拍你的肩膀告訴你這是前面3個離職員工留下的代碼

if(state === 1){
    // 一gi窩裏giaogiao
}else if(state === 2){
    // 左邊畫個龍右邊寫個bug
}else if(state === 3){
    //do something
}
.....以此類推
複製代碼

新人快速成長祕笈,那就是寫沒有接口文檔,沒有需求原型的項目,裏面充斥着這樣的數字狀態的項目

以對象取代判斷條件

const stateType = {
    start: 1,  // 開始 
    doing: 2,  // 進行中
    end: 3,    // 結束
}

if(state === stateType['start']){
    //  一gigiaogiao裏giaogiao
}else if(state === stateType['doing']){
    // 左邊畫個龍右邊寫個bug
}else if(state === stateType['end']){
    // do something
}
複製代碼

不要以爲多了一個對象代碼就變冗餘了,這個對象中的key正是維護這份代碼最好的註釋

以函數取代判斷條件

以一個電商活動節日爲例,要求18歲以上,女生優惠比男生優惠力度大

if(sex==='feMale' && age>18) {
    charge = (quantity * count) - 800; // 男生優惠800元
}else{
    charge = (quantity * count)*0.8 - 500; // 女生8折再優惠500元
}
複製代碼
分解條件的方式改造

1.函數取代判斷條件

function allowAge(){
    return sex==='feMale' && age>18;
}
複製代碼

2.分解執行函數

function  maleCharge(){
    return (quantity * count) - 800;
}

 function  femaleCharge(){
    return (quantity * count)*0.8 - 500;
}
複製代碼

3.縮成簡單三元

charge = allowAge() ? femaleCharge() : maleCharge();
複製代碼

執行語句都被封裝起來且變得簡短易懂

騷操做

1.若是有不執行的條件,爲了減小沒必要要的代碼提早return

function allowAge(age){
     if (age<'18') throw new Error('No adult!');
     // 正常
}
複製代碼

2.給參數設置默認值,這樣就不須要作undefined類型處理和提早return了

function  maleCharge(count=5){ 
    // if (count<5) return false;
    return (quantity * count) - 800;
}
複製代碼

3.將多個簡單條件放在數組對象裏使用includes

if(fruit === 'apple'||fruit === 'banana'||fruit === 'lemon') eatFruit()

if(['apple','banana','lemon'].includes(fruit)) eatFruits()
複製代碼

4.當狀態比較多的時候能夠用這種方式來包裝

es6中的Map容許使用對象來做爲key

const worklist = () => { 
    return new Map([
      [{period:'morning',workProgress:'start'},()=>{/* 上班 */}],
      [{period:'afternoon',workProgress:'end'},()=>{/* 上班 */}],
      [{period:'night',workProgress:'doing'},()=>{/* 加班 */}],
      [{period:'night',workProgress:'start'},()=>{/* 加班 */}],
      [{period:'night',workProgress:'end'},()=>{/* 下班 */}],
      //...
    ])
}
複製代碼

利用對象作爲key能夠存儲多個數據(條件)

function getWorkState (){
  const todayWorkState = [...worklist()].filter(([key])=>(key.period == period && key.workProgress == workProgress));
  return todayWorkState[0][1];
}

const workState = getWorkState ();
複製代碼

若是你看完以後滿腦子的加班上班,那說明你看懂了!

若是以爲不錯,請素質四連,點贊、關注、轉發、評論,畢竟要恰飯的嘛

相關文章
相關標籤/搜索