国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[淺析]特定場景下取代if-else和switch的方案

simpleapples / 1414人閱讀

摘要:日后的維護(hù)可能存在問題。比如輸入一個(gè)景點(diǎn),給出景點(diǎn)所在的城市。廣州塔廣州花城廣場廣州白云山廣州西湖杭州湘湖杭州京杭大運(yùn)河杭州砂之船生活廣場杭州南宋御街杭州有些人不習(xí)慣對象的名是中文。小結(jié)最近在特定場合下,代替和的解決方案就是這么多了。

世界那么大,景點(diǎn)那么多。有些時(shí)候,換個(gè)方式,換個(gè)角度,換個(gè)陪同,都會(huì)有不一樣感覺與收獲。寫代碼也亦如此。
1.前言

相信很多人有這樣的經(jīng)歷,在項(xiàng)目比較忙的時(shí)候,都是先考慮實(shí)現(xiàn),用當(dāng)時(shí)以為最好的方式先實(shí)現(xiàn)方案,在項(xiàng)目不忙的時(shí)候,再看下以前代碼,想下有什么更好的實(shí)現(xiàn)方案,或者優(yōu)化方案。筆者也不例外,下面就和讀者們分享一下自己最近在特定場合下,代替if-else,switch的解決方案。如果大家有什么想法,歡迎在評論區(qū)內(nèi)留言,大家多多交流。

2.look-up表代替if-else

比如大家可能會(huì)遇到類似下面的需求:比如某平臺(tái)的信用分?jǐn)?shù)評級,超過700-950,就是信用極好,650-700信用優(yōu)秀,600-650信用良好,550-600信用中等,350-550信用較差。

實(shí)現(xiàn)很簡單

function showGrace(grace) {
    let _level="";
    if(grace>=700){
        _level="信用極好"
    }
    else if(grace>=650){
        _level="信用優(yōu)秀"
    }
    else if(grace>=600){
        _level="信用良好"
    }
    else if(grace>=550){
        _level="信用中等"
    }
    else{
        _level="信用較差"
    }
    return _level;
}

運(yùn)行也沒問題,但是問題也是有

1.萬一以后需求,改了比如650-750是信用優(yōu)秀,750-950是信用極好。這樣就整個(gè)方法要改。

2.方法存在各種神仙數(shù)字:700,650,600,550。日后的維護(hù)可能存在問題。

3.if-else太多,看著有點(diǎn)強(qiáng)迫癥

所以下面用look-up表,把配數(shù)據(jù)置和業(yè)務(wù)邏輯分離的方式實(shí)現(xiàn)下

function showGrace(grace) {
    let graceForLevel=[700,650,600,550];
    let levelText=["信用極好","信用優(yōu)秀","信用良好","信用中等","信用較差"];
    for(let i=0;i=graceForLevel[i]){
            return levelText[i];
        }
    }
    //如果不存在,那么就是分?jǐn)?shù)很低,返回最后一個(gè)
    return levelText[levelText.length-1];
}

這樣的修改,優(yōu)點(diǎn)就是如果有需求修改,只需要修改graceForLevel,levelText。業(yè)務(wù)邏輯不需要改。

為什么這里推薦配數(shù)據(jù)置和業(yè)務(wù)邏輯分離

1.修改配置數(shù)據(jù)比業(yè)務(wù)邏輯修改成本更小,風(fēng)險(xiǎn)更低

2.配置數(shù)據(jù)來源和修改都可以很靈活

3.薦配置和業(yè)務(wù)邏輯分離,可以更快的找到需要修改的代碼

如果還想靈活一些,可以封裝一個(gè)稍微通用一點(diǎn)的look-up函數(shù)。

function showGrace(grace,level,levelForGrace) {
    for(let i=0;i=level[i]){
            return levelForGrace[i];
        }
    }
    //如果不存在,那么就是分?jǐn)?shù)很低,返回最后一個(gè)
    return levelForGrace[levelForGrace.length-1];
}
let graceForLevel=[700,650,600,550];
let levelText=["信用極好","信用優(yōu)秀","信用良好","信用中等","信用較差"];

使用推薦配置數(shù)據(jù)和業(yè)務(wù)邏輯分離形式開發(fā),還有一個(gè)好處,在上面例子沒體現(xiàn)出來,下面簡單說下。比如輸入一個(gè)景點(diǎn),給出景點(diǎn)所在的城市。

function getCityForScenic(scenic) {
    let _city=""
    if(scenic==="廣州塔"){
        _city="廣州"
    }
    else if(scenic==="西湖"){
        _city="杭州"
    }
    return _city;
}

輸入廣州塔,就返回廣州。輸入西湖就返回杭州。但是一個(gè)城市不止一個(gè)景點(diǎn),那么有人習(xí)慣這樣寫。

if(scenic==="廣州塔"||scenic==="花城廣場"||scenic==="白云山"){
    _city="廣州"
}

如果景點(diǎn)很多,數(shù)據(jù)很長,看著難受,有些人喜歡這樣寫

let scenicOfHangZhou=["西湖","湘湖","砂之船生活廣場","京杭大運(yùn)河","南宋御街"]
if(~scenicOfHangZhou.indexOf(scenic)){
    _city="杭州"
}

這樣執(zhí)行沒錯(cuò),但是寫出來的代碼可能像下面這樣,風(fēng)格不統(tǒng)一

function getCityForScenic(scenic) {
    let _city="";
    let scenicOfHangZhou=["西湖","湘湖","砂之船生活廣場","京杭大運(yùn)河","南宋御街"];
    if(scenic==="廣州塔"||scenic==="花城廣場"||scenic==="白云山"){
        _city="廣州"
    }
    else if(~scenicOfHangZhou.indexOf(scenic)){
        _city="杭州"
    }
    return _city;
}

即使用switch,也有可能出現(xiàn)這樣的情況

function getCityForScenic(scenic) {
    let _city="";
    let scenicOfHangZhou=["西湖","湘湖","砂之船生活廣場","京杭大運(yùn)河","南宋御街"];
    switch(true){
        case (scenic==="廣州塔"||scenic==="花城廣場"||scenic==="白云山"):_city="廣州";break;
        case (!!~scenicOfHangZhou.indexOf(scenic)):return "杭州";   
    }
    return     _city;
}

雖然上面的代碼出現(xiàn)的概率很小,但畢竟會(huì)出現(xiàn)。這樣的代碼可能會(huì)造成日后維看得眼花繚亂。如果使用了配置數(shù)據(jù)和業(yè)務(wù)邏輯分離,那就可以避免這個(gè)問題。

function getCityForScenic(scenic) {
    let cityConfig={
        "廣州塔":"廣州",
        "花城廣場":"廣州",
        "白云山":"廣州",
        "西湖":"杭州",
        "湘湖":"杭州",
        "京杭大運(yùn)河":"杭州",
        "砂之船生活廣場":"杭州",
        "南宋御街":"杭州",
    }
    
    return cityConfig[scenic];
}
有些人不習(xí)慣對象的 key 名是中文。也可以靈活處理
function getCityForScenic(scenic) {
    let cityConfig=[
        {
            scenic:"廣州塔",
            city:"廣州"
        },
        {
            scenic:"花城廣場",
            city:"廣州"
        },
        {
            scenic:"白云山",
            city:"廣州"
        },
        {
            scenic:"西湖",
            city:"杭州"
        },
        {
            scenic:"湘湖",
            city:"杭州"
        },
        {
            scenic:"京杭大運(yùn)河",
            city:"杭州"
        },
        {
            scenic:"砂之船生活廣場",
            city:"杭州"
        }
    ]
    for(let i=0;i

這樣一來,如果以后要加什么景點(diǎn),對應(yīng)什么城市,只能修改上面的cityConfig,業(yè)務(wù)邏輯不需要改,也不能改。代碼風(fēng)格上面就做到了統(tǒng)一。

這里簡單總結(jié)下,使用配置數(shù)據(jù)和業(yè)務(wù)邏輯分離的形式,好處

修改配置數(shù)據(jù)比業(yè)務(wù)邏輯修改成本更小,風(fēng)險(xiǎn)更低

配置數(shù)據(jù)來源和修改都可以很靈活

配置和業(yè)務(wù)邏輯分離,可以更快的找到需要修改的代碼

配置數(shù)據(jù)和業(yè)務(wù)邏輯可以讓代碼風(fēng)格統(tǒng)一

但是并不是所有的if-else都建議這樣改造,有些需求不建議使用look-up改造。比如if-else不是很多,if判斷的邏輯不統(tǒng)一的使用,還是建議使用if-else方式實(shí)現(xiàn)。但是神仙數(shù)字,要清除。

比如下面這個(gè)根絕傳入時(shí)間戳,顯示評論時(shí)間顯示的需求,

發(fā)布1小時(shí)以內(nèi)的評論:x分鐘前

發(fā)布1小時(shí)~24小時(shí)的評論:x小時(shí)前

發(fā)布24小時(shí)~30天的評論:x天前

發(fā)布30天以上的評論:月/日

去年發(fā)布并且超過30天的評論:年/月/日

實(shí)現(xiàn)不難,幾個(gè)if-else就行了

function formatDate(timeStr){
    //獲取當(dāng)前時(shí)間戳
    let _now=+new Date();
    //求與當(dāng)前的時(shí)間差
    let se=_now-timeStr;
    let _text="";
    //去年
    if(new Date(timeStr).getFullYear()!==new Date().getFullYear()&&se>2592000000){
      _text=new Date(timeStr).getFullYear()+"年"+(new Date(timeStr).getMonth()+1)+"月"+new Date(timeStr).getDate()+"日";
    }
    //30天以上
    else if(se>2592000000){
      _text=(new Date(timeStr).getMonth()+1)+"月"+new Date(timeStr).getDate()+"日";
    }
    //一天以上
    else if(se>86400000){
      _text=Math.floor(se/86400000)+"天前";
    }
    //一個(gè)小時(shí)以上
    else if(se>3600000){
      _text=Math.floor(se/3600000)+"小時(shí)前";
    }
    //一個(gè)小時(shí)以內(nèi)
    else{
      //如果小于1分鐘,就顯示1分鐘前
      if(se<60000){se=60000}
      _text=Math.floor(se/60000)+"分鐘前";
    }
    return _text;
}

運(yùn)行結(jié)果沒問題,但是也存在一個(gè)問題,就是這個(gè)需求有神仙數(shù)字:2592000000,86400000,3600000,60000。對于后面維護(hù)而言,一開始可能并不知道這個(gè)數(shù)字是什么東西。

所以下面就消滅神仙數(shù)字,常量化

function formatDate(timeStr){
    //獲取當(dāng)前時(shí)間戳
    let _now=+new Date();
    //求與當(dāng)前的時(shí)間差
    let se=_now-timeStr;
    const DATE_LEVEL={
      month:2592000000,
      day:86400000,
      hour:3600000,
      minter:60000,
    }
    let _text="";
    //去年
    if(new Date(timeStr).getFullYear()!==new Date().getFullYear()&&se>DATE_LEVEL.month){
      _text=new Date(timeStr).getFullYear()+"年"+(new Date(timeStr).getMonth()+1)+"月"+new Date(timeStr).getDate()+"日";
    }
    //一個(gè)月以上
    else if(se>DATE_LEVEL.month){
      _text=(new Date(timeStr).getMonth()+1)+"月"+new Date(timeStr).getDate()+"日";
    }
    //一天以上
    else if(se>DATE_LEVEL.day){
      _text=Math.floor(se/DATE_LEVEL.day)+"天前";
    }
    //一個(gè)小時(shí)以上
    else if(se>DATE_LEVEL.hour){
      _text=Math.floor(se/DATE_LEVEL.hour)+"小時(shí)前";
    }
    //一個(gè)小時(shí)以內(nèi)
    else{
      //如果小于1分鐘,就顯示1分鐘前
      if(se

運(yùn)行結(jié)果也是正確的,代碼多了,但是神仙數(shù)字沒了。可讀性也不差。

這里也順便提一下,如果硬要把上面的需求改成look-up的方式,代碼就是下面這樣。這樣代碼的修改的擴(kuò)展性會(huì)強(qiáng)一些,成本會(huì)小一些,但是可讀性不如上面。取舍關(guān)系,實(shí)際情況,實(shí)際分析。
function formatDate(timeStr){
    //獲取當(dāng)前時(shí)間戳
    let _now=+new Date();
    //求與當(dāng)前的時(shí)間差
    let se=_now-timeStr;
    let _text="";
    //求上一年最后一秒的時(shí)間戳
    let lastYearTime=new Date(new Date().getFullYear()+"-01-01 00:00:00")-1;
    //把時(shí)間差添加進(jìn)去(當(dāng)前時(shí)間戳與上一年最后一秒的時(shí)間戳的差)添加進(jìn)去,如果時(shí)間差(se)超過這個(gè)值,則代表了這個(gè)時(shí)間是上一年的時(shí)間。
    //DATE_LEVEL.unshift(_now-lastYearTime);
    const DATE_LEVEL={
      month:2592000000,
      day:86400000,
      hour:3600000,
      minter:60000,
    }
    let handleFn=[
        {
            time:DATE_LEVEL.month,
            fn:function(timeStr){
                return (new Date(timeStr).getMonth()+1)+"月"+new Date(timeStr).getDate()+"日";
            }
        },
        {
            time:DATE_LEVEL.day,
            fn:function(timeStr){
                return Math.floor(se/DATE_LEVEL.day)+"天前";
            }
        },
        {
            time:DATE_LEVEL.hour,
            fn:function(timeStr){
                return Math.floor(se/DATE_LEVEL.hour)+"小時(shí)前";
            }
        },
        {
            time:DATE_LEVEL.minter,
            fn:function(timeStr){
                return Math.ceil(se/DATE_LEVEL.minter)+"分鐘前";
            }
        } 
    ];
    //求上一年最后一秒的時(shí)間戳
    let lastYearTime=new Date(new Date().getFullYear()+"-01-01 00:00:00")-1;
    //把時(shí)間差(當(dāng)前時(shí)間戳與上一年最后一秒的時(shí)間戳的差)和操作函數(shù)添加進(jìn)去,如果時(shí)間差(se)超過這個(gè)值,則代表了這個(gè)時(shí)間是上一年的時(shí)間。
    handleFn.unshift({
        time:_now-lastYearTime,
        fn:function(timeStr){
            if(se>DATE_LEVEL.month){
                return new Date(timeStr).getFullYear()+"年"+(new Date(timeStr).getMonth()+1)+"月"+new Date(timeStr).getDate()+"日";
                
            }
        },
    });
    let result="";
    for(let i=0;i=handleFn[i].time){
            result=handleFn[i].fn(timeStr);
            if(result){
                return result;
            }
        }
    }
    //如果發(fā)布時(shí)間小于1分鐘,之際返回1分鐘
    return result="1分鐘前"
}
3.配置對象代替switch

比如有一個(gè)需求:傳入cash,check,draft,zfb,wx_pay,對應(yīng)輸出:現(xiàn)金,支票,匯票,支付寶,微信支付。

需求也很簡單,就一個(gè)switch就搞定了

function getPayChanne(tag){
    switch(tag){
        case "cash":return "現(xiàn)金";
        case "check":return "支票";
        case "draft":return "匯票";
        case "zfb":return "支付寶";
        case "wx_pay":return "微信支付";
    }
}

但是這個(gè)的硬傷還是和上面一樣,萬一下次又要多加一個(gè)如:bank_trans對應(yīng)輸出銀行轉(zhuǎn)賬呢,代碼又要改。類似的問題,同樣的解決方案,配置數(shù)據(jù)和業(yè)務(wù)邏輯分離。代碼如下。

function getPayChanne(tag){
    let payChanneForChinese = {
        "cash": "現(xiàn)金",
        "check": "支票",
        "draft": "匯票",
        "zfb": "支付寶",
        "wx_pay": "微信支付",
    };
    return payChanneForChinese[tag];
}

同理,如果想封裝一個(gè)通用的,也可以的

let payChanneForChinese = {
    "cash": "現(xiàn)金",
    "check": "支票",
    "draft": "匯票",
    "zfb": "支付寶",
    "wx_pay": "微信支付",
};
function getPayChanne(tag,chineseConfig){
    return chineseConfig[tag];
}
getPayChanne("cash",payChanneForChinese);

這里使用對象代替 switch 好處就在于

使用對象不需要 switch 逐個(gè) case 遍歷判斷。

使用對象,編寫業(yè)務(wù)邏輯可能更靈活

使用對象可以使得配置數(shù)據(jù)和業(yè)務(wù)邏輯分離。好處參考上一部分內(nèi)容。

4.小結(jié)

最近在特定場合下,代替if-else和switch的解決方案就是這么多了。if-else,switch本身沒錯(cuò),主要是想著怎么優(yōu)化代碼,讓代碼更加具有可讀性,擴(kuò)展性。如果大家還有什么優(yōu)化的方案或者對方面的方案有更好的實(shí)現(xiàn)方案。歡迎在評論區(qū)留言。

-------------------------華麗的分割線--------------------

想了解更多,關(guān)注關(guān)注我的微信公眾號:守候書閣

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/96147.html

相關(guān)文章

  • 前端性能優(yōu)化之 JavaScript

    摘要:大多數(shù)情況下,對一個(gè)直接量和一個(gè)局部變量數(shù)據(jù)訪問的性能差異是微不足道的。 前端性能優(yōu)化之 JavaScript 前言 本文為 《高性能 JavaScript》 讀書筆記,是利用中午休息時(shí)間、下班時(shí)間以及周末整理出來的,此書雖有點(diǎn)老舊,但談?wù)摰男阅軆?yōu)化話題是每位同學(xué)必須理解和掌握的,業(yè)務(wù)響應(yīng)速度直接影響用戶體驗(yàn)。 一、加載和運(yùn)行 大多數(shù)瀏覽器使用單進(jìn)程處理 UI 更新和 JavaScri...

    Coding01 評論0 收藏0
  • 編程技巧:嘗試不用 If 語句編程

    摘要:兩個(gè)例子比較而言,語句的實(shí)現(xiàn)可能更具兼容性,可以適應(yīng)于數(shù)組元素是小數(shù)的情況。若數(shù)組元素為浮點(diǎn)類型,第二個(gè)例子就無法正常使用。開發(fā)環(huán)境推薦是基于瀏覽器的集成式開發(fā)環(huán)境,支持絕大部分編程語言,包括小程序等等,無需下載安裝程序,一鍵切換開發(fā)環(huán)境。 Coding Tip: Try to Code Without If-statements showImg(https://segmentfaul...

    jackwang 評論0 收藏0
  • 【前端】重構(gòu)方案了解一

    摘要:定義公共組件供各模塊或特定場景調(diào)用,復(fù)用度高第三方庫組件插件庫用于解決以下版本瀏覽器對新增標(biāo)簽不識(shí)別,并導(dǎo)致不起作用的問題。 前端重構(gòu)方案 前言 前端技術(shù)發(fā)展很快,很多項(xiàng)目面臨前端部分重構(gòu),很開心可以讓我進(jìn)行這次項(xiàng)目前端的重構(gòu)方案編寫,在思考的同時(shí)參考了網(wǎng)上很多資料,希望本篇重構(gòu)方案有一定的完整性,可以帶給大家一些在面臨重構(gòu)時(shí)有用的東西,同時(shí)希望路過的大牛小牛不領(lǐng)賜教,能給我略微指點(diǎn)...

    ningwang 評論0 收藏0
  • JS基礎(chǔ)學(xué)習(xí)04「語句」

    摘要:表達(dá)式用來計(jì)算出一個(gè)值,語句用來執(zhí)行以使某件事發(fā)生。其中,語句會(huì)立即退出循環(huán),強(qiáng)制繼續(xù)執(zhí)行循環(huán)后面的語句。在執(zhí)行語句之后,結(jié)果顯示。語句語句的作用是指定函數(shù)調(diào)用后的返回值。語句語句的作用是把程序運(yùn)行時(shí)產(chǎn)生的錯(cuò)誤顯式地拋出異常。 表達(dá)式在 JavaScript 中是短語,那么語句就是整句命令。表達(dá)式用來計(jì)算出一個(gè)值,語句用來執(zhí)行以使某件事發(fā)生。從本質(zhì)上看,語句定義了 JavaScript...

    remcarpediem 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<