特定场景下取代if-else和switch的方式
look-up表代替if-else
比如某平臺的信用分數評級:
超過700-950,信用極好,
650-700信用優秀,
600-650信用良好,
550-600信用中等,
350-550信用較差。
常規寫法:
function showGrace(grace) {let _level='';if(grace>=700){_level='信用極好'}else if(grace>=650){_level='信用優秀'}else if(grace>=600){_level='信用良好'}else if(grace>=550){_level='信用中等'}else{_level='信用較差'}return _level; }看看運行也沒問題,但是問題也是有的比如:
1- 萬一以后需求,改了比如650-750是信用優秀,750-950是信用極好。這樣就整個方法要改。
2- 方法存在各種神仙數字:700,650,600,550。日后的維護可能存在問題。
3- if-else太多,看著有點強迫癥
用look-up表,把配數據置和業務邏輯分離的方式實現下
function showGrace(grace) {let graceForLevel=[700,650,600,550];let levelText=['信用極好','信用優秀','信用良好','信用中等','信用較差'];for(let i=0;i<graceForLevel.length;i++){if(grace>=graceForLevel[i]){return levelText[i];}}//如果不存在,那么就是分數很低,返回最后一個return levelText[levelText.length-1]; }這樣的修改,優點就是如果有需求修改,只需要修改graceForLevel,levelText。業務邏輯不需要改。
為什么這里推薦配數據置和業務邏輯分離
1.修改配置數據比業務邏輯修改成本更小,風險更低
2.配置數據來源和修改都可以很靈活
3.薦配置和業務邏輯分離,可以更快的找到需要修改的代碼
如果還想靈活一些,可以封裝一個稍微通用一點的look-up函數。
通用一點的look-up函數
function showGrace(grace,level,levelForGrace) {for(let i=0;i<level.length;i++){if(grace>=level[i]){return levelForGrace[i];}}//如果不存在,那么就是分數很低,返回最后一個return levelForGrace[levelForGrace.length-1]; } let graceForLevel=[700,650,600,550]; let levelText=['信用極好','信用優秀','信用良好','信用中等','信用較差'];第二個實例:
比如輸入一個景點,給出景點所在的城市。
最low的辦法:
function getCityForScenic(scenic) {let _city=''if(scenic==='廣州塔'){_city='廣州'}else if(scenic==='西湖'){_city='杭州'}return _city; }次low的辦法:
function getCityForScenic(scenic) {let _city='';let scenicOfHangZhou=['西湖','湘湖','砂之船生活廣場','京杭大運河','南宋御街'];if(scenic==='廣州塔'||scenic==='花城廣場'||scenic==='白云山'){_city='廣州'}else if(~scenicOfHangZhou.indexOf(scenic)){_city='杭州'}return _city; }次次low的辦法: (采用 switch case)
function getCityForScenic(scenic) {let _city='';let scenicOfHangZhou=['西湖','湘湖','砂之船生活廣場','京杭大運河','南宋御街'];switch(true){case (scenic==='廣州塔'||scenic==='花城廣場'||scenic==='白云山'):_city='廣州';break;case (!!~scenicOfHangZhou.indexOf(scenic)):return '杭州'; }return _city; }雖然上面的代碼出現的概率很小,但畢竟會出現。這樣的代碼可能會造成日后維看得眼花繚亂。如果使用了配置數據和業務邏輯分離,那就可以避免這個問題。
配置數據和業務邏輯分離
function getCityForScenic(scenic) {let cityConfig={'廣州塔':'廣州','花城廣場':'廣州','白云山':'廣州','西湖':'杭州','湘湖':'杭州','京杭大運河':'杭州','砂之船生活廣場':'杭州','南宋御街':'杭州',}return cityConfig[scenic]; }不習慣對象的 key 名是中文。也可以靈活處理
function getCityForScenic(scenic) {let cityConfig=[{scenic:'廣州塔',city:'廣州'},{scenic:'花城廣場',city:'廣州'},{scenic:'白云山',city:'廣州'},{scenic:'西湖',city:'杭州'},{scenic:'湘湖',city:'杭州'},{scenic:'京杭大運河',city:'杭州'},{scenic:'砂之船生活廣場',city:'杭州'}]for(let i=0;i<cityConfig.length;i++){if(cityConfig[i].scenic===scenic){return cityConfig[i].city}} }這里簡單總結下,使用配置數據和業務邏輯分離的形式,好處
1- 修改配置數據比業務邏輯修改成本更小,風險更低
2- 配置數據來源和修改都可以很靈活
3- 配置和業務邏輯分離,可以更快的找到需要修改的代碼
4- 配置數據和業務邏輯可以讓代碼風格統一
但是并不是所有的if-else都建議這樣改造,有些需求不建議使用look-up改造。比如if-else不是很多,if判斷的邏輯不統一的使用,還是建議使用if-else方式實現。但是神仙數字,要清除。
配置對象代替switch
比如有一個需求:傳入cash,check,draft,zfb,wx_pay,對應輸出:現金,支票,匯票,支付寶,微信支付。
需求也很簡單,就一個switch就搞定了
function getPayChanne(tag){switch(tag){case 'cash':return '現金';case 'check':return '支票';case 'draft':return '匯票';case 'zfb':return '支付寶';case 'wx_pay':return '微信支付';} }但是這個的硬傷還是和上面一樣,萬一下次又要多加一個如:bank_trans對應輸出銀行轉賬呢,代碼又要改。類似的問題,同樣的解決方案,配置數據和業務邏輯分離。代碼如下。
function getPayChanne(tag){let payChanneForChinese = {'cash': '現金','check': '支票','draft': '匯票','zfb': '支付寶','wx_pay': '微信支付',};return payChanneForChinese[tag]; }同理,如果想封裝一個通用的,也可以的
let payChanneForChinese = {'cash': '現金','check': '支票','draft': '匯票','zfb': '支付寶','wx_pay': '微信支付', }; function getPayChanne(tag,chineseConfig){return chineseConfig[tag]; } getPayChanne('cash',payChanneForChinese);總結:
在特定場合下,代替if-else和switch的解決方案就是這么多了。if-else,switch本身沒錯,主要是想著怎么優化代碼,讓代碼更加具有可讀性,擴展性。
總結
以上是生活随笔為你收集整理的特定场景下取代if-else和switch的方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 欧盟计划于 2024 年起禁止使用镀铬材
- 下一篇: 呱太中谁最怕黑