<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          讓你的 JS 代碼變得更加優(yōu)雅且可維護(hù)

          共 440字,需瀏覽 1分鐘

           ·

          2021-01-21 08:14

          • 作者:陳大魚頭
          • github:KRISACHAN

          魚頭在開發(fā)的過程中,總結(jié)了一些優(yōu)化開發(fā)的編碼經(jīng)驗(yàn),當(dāng)然這些經(jīng)驗(yàn)都是前人總結(jié)出來的,這次就特別拿出來跟大家一起分享,當(dāng)然這些經(jīng)驗(yàn)不一定是最佳實(shí)踐,各位讀者有興趣或者有不同意見的可以跟魚頭一起探討一下。

          拒絕魔法

          眾所周知,魔法是這樣的:

          哦,不是。。

          在編程的世界里也有魔法,一般稱其為:魔法數(shù)字,魔法變量,魔法字符串。例如這樣:

          const?a?=?await?abcdefg();
          console.log(a?===?200);
          const?b?=?await?asdfgh();
          if?(b?===?0)?{
          }?else?if?(b?===?1)?{
          }?else?if?(b?===?2)?{};
          for?(let?i?=?0;?i?10;?i++)?{};

          以上直接出現(xiàn)的,莫名其妙的變量名,字符串以及判斷條件數(shù)字,就叫魔法。。。

          這種寫法寫出來的代碼晦澀難懂,難以維護(hù),隱藏 BUG 多,除非你準(zhǔn)備給接手的人埋坑,或者準(zhǔn)備辭職,不然千萬別這么寫(容易被打斷腿,????? )

          那么怎么寫才更優(yōu)雅?

          語義化

          首先便是語義化。一個(gè)是變量,常量的語義化,例如:

          const?SUCCESS_STATUS?=?200;
          const?requestStatus?=?await?getStatus();
          console.log(requestStatus?===?SUCCESS_STATUS);
          const?userRole?=?await?getUserRole();
          const?GUEST_CODE?=?0;
          const?USER_CODE?=?1;
          const?ADMIN_CODE?=?2;
          if?(userRole?===?GUEST_CODE)?{
          }?else?if?(userRole?===?USER_CODE)?{
          }?else?if?(userRole?===?ADMIN_CODE)?{};
          const?MAX_NUM?=?10;
          const?MIN_NUM?=?0;
          for?(let?currentNum?=?MIN_NUM;?currentNum?

          一般的規(guī)則就是變量用小寫,常量用大寫,把變量名語義化,那么當(dāng)你看到這段代碼的時(shí)候,一眼就能知道它是做什么的,而不是非得要浪費(fèi)時(shí)間看完上下文,或者是猜。

          枚舉

          對(duì)于上面判斷 userRole 的代碼,其實(shí)我們可以用更優(yōu)雅的方式去實(shí)現(xiàn),那就是 枚舉 。

          按照維基百科的說明:在數(shù)學(xué)和計(jì)算機(jī)科學(xué)理論中,一個(gè)集的枚舉是列出某些有窮序列集的所有成員的程序,或者是一種特定類型對(duì)象的計(jì)數(shù)。這兩種類型經(jīng)常(但不總是)重疊。

          其實(shí)就是組織收集有關(guān)聯(lián)變量的一種方式。枚舉的好處在于方便多狀態(tài)的管理,以及可讀性更強(qiáng)。例如:

          const?ROLES?=?{
          ??GUEST:?0,
          ??USER:?1,
          ??ADMIN:?2
          };
          const?userRole?=?await?getUserRole();
          if?(userRole?===?ROLES.GUEST)?{
          }?else?if?(userRole?===?ROLES.USER)?{
          }?else?if?(userRole?===?ROLES.ADMIN)?{};

          通過枚舉的方式歸納起來,維護(hù)起來更方便,而且要添加狀態(tài)直接在 ROLES 對(duì)象里寫就行,更方便快捷。

          策略模式

          維基百科上說:策略模式作為一種軟件設(shè)計(jì)模式,指對(duì)象有某個(gè)行為,但是在不同的場(chǎng)景中,該行為有不同的實(shí)現(xiàn)算法。

          上面的代碼依舊是可優(yōu)化的,在這里我們可以利用策略模式來做進(jìn)一層的優(yōu)化。

          具體的例子就是如下:

          const?ROLES?=?{
          ??GUEST:?0,
          ??USER:?1,
          ??ADMIN:?2
          };
          const?ROLE_METHODS?=?{
          ??[ROLES.GUEST]()?{},
          ??[ROLES.USER]()?{},
          ??[ROLES.ADMIN]()?{},
          };
          const?userRole?=?await?getUserRole();
          ROLE_METHODS[userRole]();

          通過上面的寫法,我們可以知道,當(dāng)我們需要增加角色,或者修改角色數(shù)字的時(shí)候,只需要修改 ROLES 里對(duì)應(yīng)的字段,以及 ROLE_METHODS 里的方法即可,這樣我們就可以將可能很冗長(zhǎng)的 if...else 代碼給抽離出來,顆粒度更細(xì),更好維護(hù)。

          更在狀態(tài)

          除了上面的方式之外,我們還可以利用“ 狀態(tài) ”的概念來寫代碼。在看代碼之前,我們先了解下什么是 “有限狀態(tài)機(jī)”。

          根據(jù)維基百科的解釋:有限狀態(tài)機(jī)(英語:finite-state machine,縮寫:FSM)又稱有限狀態(tài)自動(dòng)機(jī)(英語:finite-state automation,縮寫:FSA),簡(jiǎn)稱狀態(tài)機(jī),是表示有限個(gè)狀態(tài)以及在這些狀態(tài)之間的轉(zhuǎn)移和動(dòng)作等行為的數(shù)學(xué)計(jì)算模型。

          例如我們熟悉的 Promise ,它就是在狀態(tài)集:PENDIN 、 FULFILLEDREJECTED ?之間單向流轉(zhuǎn)的有限狀態(tài)機(jī)。

          狀態(tài)機(jī)的概念跟策略模式類似,實(shí)現(xiàn)方式也類似,這里面最大的不同是在于 “語義” 。

          策略模式更適合于互不依賴,同時(shí)只能存在一個(gè)狀態(tài)的場(chǎng)景,例如:

          const?吃?=?{
          ??沙縣大酒店()?{
          ????吃云吞()
          ??},
          ??開封菜()?{
          ????吃漢堡()
          ??},
          ??在家()?{
          ????吃外賣()
          ??}
          };

          這里面如果我們肚子餓了,就只能在 沙縣大酒店()開封菜()在家() 這幾個(gè)狀態(tài)里選。

          你不能都吃,當(dāng)然以下情況除外。。。

          如果是狀態(tài)模式,則會(huì)有這種情況:

          const?打工人?=?{
          ??起床()?{},
          ??上班()?{},
          ??加班()?{},
          ??下班()?{}
          };
          //?早上6點(diǎn)
          打工人.起床();
          //?早上9點(diǎn)
          打工人.上班();
          //?晚上6點(diǎn)
          打工人.加班();
          //?晚上12點(diǎn)
          打工人.下班();

          這里的打工人根據(jù)不同的時(shí)間,進(jìn)行不同的任務(wù),便是打工人模式,哦不,狀態(tài)模式。這里的時(shí)間就是狀態(tài)。

          我們舉個(gè)實(shí)際的業(yè)務(wù)例子,就是訂單列表頁,通常我們的訂單可能有這幾種狀態(tài):

          不同的狀態(tài)展示的 UI 也不同,所以我們以不同的狀態(tài)劃分好模塊之后,代碼寫起來就會(huì)清晰很多,我們以 Vue 代碼為例:

          //?contants.js
          export?const?ORDER_STATUS?=?{
          ??INIT:?0,?//?初始化
          ??CREATED:?1,?//?訂單創(chuàng)建
          ??ARREARAGE:?2,?//?待支付
          ??PURCHASED:?3,?//?已購買
          ??SHIPPED:?4,?//?已發(fā)貨
          ??COMPLETED:?5?//?已完成
          };
          // order.vue



          將頁面組件按狀態(tài)劃分,實(shí)現(xiàn)獨(dú)立自治,這樣子既能防止代碼耦合,方便維護(hù) debug,也方便開發(fā)者自測(cè),如果需要看不同狀態(tài)的展示效果,只要手動(dòng)給 orderStatus 賦值即可,方便快捷。

          面向切面

          按照維基百科的解釋:面向切面的程序設(shè)計(jì)(Aspect-oriented programming,AOP,又譯作面向方面的程序設(shè)計(jì)、剖面導(dǎo)向程序設(shè)計(jì))是計(jì)算機(jī)科學(xué)中的一種程序設(shè)計(jì)思想,旨在將橫切關(guān)注點(diǎn)與業(yè)務(wù)主體進(jìn)行進(jìn)一步分離,以提高程序代碼的模塊化程度。

          上面這段文字估計(jì)沒有什么人看,算了,直接上代碼吧

          我們看回上面打工人的場(chǎng)景,假定老板想要知道打工人每個(gè)狀態(tài)開始前跟結(jié)束前的時(shí)間以及做點(diǎn)什么,那么該怎么做呢?這個(gè)時(shí)候我們不難想到可以直接往狀態(tài)函數(shù)里寫代碼,例如:

          const?打工人?=?{
          ??起床()?{
          ????老板.start();
          ????打工人.do();
          ????老板.end();
          ??},
          ??上班()?{
          ????老板.start();
          ????打工人.do();
          ????老板.end();
          ??},
          ??加班()?{
          ????老板.start();
          ????打工人.do();
          ????老板.end();
          ??},
          ??下班()?{
          ????老板.start();
          ????打工人.do();
          ????老板.end();
          ??}
          };
          //?早上6點(diǎn)
          打工人.起床();
          //?早上9點(diǎn)
          打工人.上班();
          //?晚上6點(diǎn)
          打工人.加班();
          //?晚上12點(diǎn)
          打工人.下班();

          但是這樣打工人一下子就察覺到到了老板在監(jiān)控他的生活,如果要做到不被人察覺(不影響業(yè)務(wù)邏輯),那我們既可以采用 AOP 的實(shí)現(xiàn)方式。代碼如下:

          import?eq?from?'lodash';
          const?TYPES?=?{
          ??FUNCTION:?'function'
          }
          const?老板監(jiān)控中的打工人?=?new?Proxy(打工人,?{
          ????get(target,?key,?value,?receiver)?{
          ????????console.log('老板開始看你了~');
          ???????const?res?=?Reflect.get(target,?key,?value,?receiver);
          ???????const?打工人任務(wù)?=?eq(typeof?res,?TYPES.FUNCTION)???res()?:?res;
          ????????console.log('老板開始記你小本本了~');
          ????????return?()?=>?打工人任務(wù);
          ????}
          });

          所以我們可以看到以下結(jié)果:

          這樣子,我們就可以輕松簡(jiǎn)單地監(jiān)控到了打工人每天干的活,而且還不讓打工人發(fā)現(xiàn),簡(jiǎn)直是資本家聽了都流淚呀。


          瀏覽 94
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲艾薇在线观看 | 狠狠搞大香蕉 | 操逼逼逼逼逼 | GOGO大胆无码人体免费视频 | 三级大香焦 |