<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>

          如何寫出不可替代的代碼?

          共 14932字,需瀏覽 30分鐘

           ·

          2022-08-15 23:27

          前言

          本文是學(xué)習(xí)《重構(gòu):改善既有代碼的設(shè)計(jì)》后的一些心得,希望能用趣味的方式結(jié)合一些實(shí)例帶領(lǐng)大家一起學(xué)習(xí),提升自身代碼質(zhì)量。

          想必最近的互聯(lián)網(wǎng)裁員消息大家也有所耳聞,那么我們怎么才能夠在這樣的大環(huán)境下茍住自身呢?經(jīng)過我的總結(jié),我認(rèn)為大家都不具備不可替代性。

          什么叫不可替代性呢,通俗點(diǎn)來說就是,這活除了你別人都干不了。達(dá)到這種境界無異于兩種情況,一種是自身過于優(yōu)秀,優(yōu)秀到?jīng)]人能取代(該情況過少,希望大家能正視己身)。

          另一種方法則是,制作出專屬于你的代碼!!下面我們來一起學(xué)習(xí),怎樣寫出專屬于你,不可被替代的代碼!

          以下不可替代寫法皆為反面教材!!!

          一、神秘命名(Mysterious Name)

          命名讓人猜不透,摸不準(zhǔn)!

          不可替代寫法:

          const getPNum = (number) => {
            ......
          }

          無論是函數(shù)命名還是入?yún)⒚嘈哦己茈y有人能參透你的深意,在別人接手你的代碼時(shí),必定會來向你請教,這在老板眼里你的價(jià)值將更為突出。

          正常寫法:

          const getPhoneCode = (phoneNumber) => {
            ......
          }

          從函數(shù)的駝峰命名我們可以很輕易猜出是獲取手機(jī)驗(yàn)證碼,入?yún)⒁材懿鲁鍪鞘謾C(jī)號碼的意思,這樣的代碼太通俗易懂了,顯然達(dá)不到我們的效果。

          二、重復(fù)代碼(Duplicated Code)&& 過長函數(shù)(Long Function)

          重復(fù)編寫大量相同代碼,內(nèi)容過多的函數(shù),使代碼變得臃腫難以維護(hù)

          不可替代寫法:

          const showUserInfo = () => {
            let totalAmount = 0;
            const userInfo = request.get('/userInfo''admin')
            const userAmountList = request.get('/userAmountList''admin')
            console.log('name', userInfo.name);
            console.log('age', userInfo.age);
            console.log('sex', userInfo.sex);
            console.log('address', userInfo.address);
            for(let i of userAmountList) {
              totalAmount += i.amount
            }
            console.log('總金額', totalAmount);
          }

          大量重復(fù)的代碼讓人瞬間產(chǎn)生疲勞感,完全不搭邊的代碼順序混淆人的雙眼,如果再加上一些神秘命名,必將讓代碼更上一個(gè)臺階。

          正常寫法:

          const showUserInfo = () => {
            const printUserDetail = (userInfo) => {
              const { name, age, sex, address } = userInfo;
              console.log('name', name);
              console.log('age', age);
              console.log('sex', sex);
              console.log('address', address);

            const printTotalAmount = (userAmountList) => {
              const totalAmount = userList.reduce((pre, cur) => pre + cur.amount, 0)
              console.log('總金額', totalAmount);
            }
            
            // 獲取用戶信息
            const userInfo = request.get('/userInfo''admin')
            printUserDetail(userInfo)
            
            // 獲取用戶金額列表
            const userAmountList = request.get('/userAmountList''admin')
            printTotalAmount(userAmountList)
          }

          重復(fù)代碼都被提煉到單獨(dú)的函數(shù)模塊中,用reduce免去了重復(fù)的代碼相加,并且代碼順序也被移動至有關(guān)聯(lián)的地方,這樣的代碼換做剛學(xué)前端的小白恐怕也能看懂,這樣明顯不能凸顯自身的獨(dú)特。

          三、過長參數(shù)列表(Long Parameter List)

          函數(shù)或組件的參數(shù)過多,影響代碼可讀性,某些環(huán)境甚至?xí)π阅茉斐捎绊?/p>

          不可替代寫法:

          const getList = (id, name, age, address, sex) => {
            ...
          }

          正常寫法:

          const getList = (data) => {
            const { id, name, age, address, sex } = data;
            ...
          }

          將入?yún)⒎胖玫揭粋€(gè)對象中,再到函數(shù)里通過解構(gòu)的方式進(jìn)行調(diào)用。這樣的方式太過簡潔,過少的入?yún)⑼癸@不出你這個(gè)函數(shù)的重要性。

          四、全局?jǐn)?shù)據(jù)

          將數(shù)據(jù)全部掛載到全局,導(dǎo)致內(nèi)存不及時(shí)被釋放以及全局污染

          不可替代寫法:

          const id = 1;
          const data1 = request.get('/userInfo', id)
          const data2 = request.get('/userState', id)

          const getUserInfo = () => {
            ...
          }

          const getUserState = () => {
            ...
          }

          所有變量放入全局,把后續(xù)開發(fā)者的路變窄,不敢隨意去更改變量,此刻再加上神秘命名,相信沒有人能夠取代你的位置。

          正常寫法:

          const id = 1;

          const getUserInfo = () => {
            const data = request.get('/userInfo', id)
            ...
          }

          const getUserState = () => {
            const data = request.get('/userState', id)
            ...
          }

          id作為多處用到變量,寫到全局,剩下的局部變量都寫在各自函數(shù)中,即不會引起全局污染,也不會擔(dān)心命名重復(fù)的問題。在各自的作用域中作用也清晰明了。

          五、發(fā)散式變化(Divergent Change)

          將需要做的事分散到各個(gè)地方,每次修改需要修改對應(yīng)函數(shù),修改不當(dāng)會導(dǎo)致另一個(gè)依賴此函數(shù)的功能崩塌

          不可替代寫法:

          const getPrice = (list) => {
            const printName = (item) => {
              if(item.type === 'totalList') {
                console.log('totalName', item.name);
              }else if(item.type === 'frozenList'){
                console.log('frozenName', item.name);
              }
            }
            
            const calcPrice = (item) => {
              if(item.type === 'totalList') {
                // todo: 計(jì)算totalPrice
                const price = ...;
                return price;
              }else if(item.type === 'frozenList'){
                // todo: 計(jì)算frozenPrice
                const price = ...;
                return price;
              }
            }
            
            printName(list.totalList);
            printName(list.frozenList);
            return calcPrice(list.totalList) - calcPrice(list.frozenList)
          }

          將方法寫成公用方法,在每次修改或者新增時(shí)候都需要去修改對應(yīng)的方法。無法知道每個(gè)價(jià)格對應(yīng)著哪些操作,當(dāng)增加一個(gè)新的價(jià)格類型時(shí),需要同時(shí)去多個(gè)函數(shù)中添加對應(yīng)的判斷邏輯。一不注意就會忘加漏加形成bug。測試績效max!

          正常寫法:

          const getPrice = (list) => {
            const totalPrice = (item) => {
              // todo: 計(jì)算totalPrice
              const price = ...
              console.log('totalName', item.name);
              console.log('price', price);
            }
            
            const frozenPrice = (item) => {
              // todo: 計(jì)算frozenPrice
              const price = ...
              console.log('frozenName', item.name);
              console.log('price', price);
            }
            
            return totalPrice(list.totalList) - frozenPrice(list.frozenList)
          }

          每個(gè)價(jià)格對應(yīng)需要的操作都被提煉到單獨(dú)的函數(shù),專注于負(fù)責(zé)自己的事,如果價(jià)格計(jì)算方式需要改變,可以更加直觀的修改。若需要添加新的價(jià)格品種,也將會更好添加。

          六、霰彈式修改(Shotgun Surgery)

          多處共用一個(gè)屬性,不設(shè)置全局變量管理,每次修改需要修改大量代碼

          不可替代寫法:

          getList(globalModel.id)
          getUserInfo(globalModel.id)
          getUserAmount(globalModel.id)

          當(dāng)需求改變,需要在多處進(jìn)行修改,這樣的工作量倍增,會讓你的工作力max!

          正常寫法:

          const id = globalModel.id;
              
          getList(id)
          getUserInfo(id)
          getUserAmount(id)

          同一個(gè)屬性被多處使用,使用一個(gè)變量進(jìn)行存儲,當(dāng)需求發(fā)生改變(例如globalModel.id變?yōu)間lobalModel.userId),只需要修改一處便能完成,大大節(jié)省時(shí)間。

          七、依戀情結(jié)(Feature Envy)

          大量引入其他函數(shù)或模塊方法,導(dǎo)致代碼耦合度極高,動一處則牽扯全身

          不可替代寫法:

          class Price {
            constructor() {}
            
            add(...num) {
              return num.reduce((pre, cur) => pre + cur, 0);
            }
            
            dataFilter(value) {
              return parseInt(value.substring(0, value.length - 2)) * 100;
            }
          }

          class Amount {
            constructor() {}
            
            getAmount(amountList) {
              const _amountList = amountList.map(item => {
                return new Price().dataFilter(item);
              });
              return new Price().add(..._amountList);
            }
          }

          所有的計(jì)算函數(shù)全部使用其他類里的方法,形成大量依賴。你要出事我跟著一起死,我就是要用你的,我就是玩~

          正常寫法:

          class Amount {
            constructor() {}
            
            add(...num) {
              return num.reduce((pre, cur) => pre + cur, 0);
            }
            
            dataFilter(value) {
              return parseInt(value.substring(0, value.length - 2)) * 100;
            }
            
            getAmount(amountList) {
              const _amountList = amountList.map(item => {
                return this.dataFilter(item);
              });
              return this.add(..._amountList);
            }
          }

          類里所有使用的方法都在本身完成,所有的問題都在自身解決,形成閉環(huán)。

          八、數(shù)據(jù)泥團(tuán)(Data Clumps)

          眾多數(shù)據(jù)糅合在一起,當(dāng)其中某一項(xiàng)數(shù)據(jù)失去意義時(shí),其他項(xiàng)數(shù)據(jù)也失去意義。

          不可替代寫法:

          const lastName = "盧"
          const firstName = "本偉"
          const name = `${lastName}${firstName}`

          發(fā)現(xiàn)當(dāng)其中某個(gè)變量失去意義的時(shí)候,另一個(gè)變量也失去意義,一損俱損。

          正常寫法:

          const person = {
            lastName"盧",
            firstName"本偉"
          }
          const name = `${person.lastName}${person.firstName}`

          有強(qiáng)聯(lián)系的數(shù)據(jù),應(yīng)為它們產(chǎn)生一個(gè)新對象。

          九、基本類型偏執(zhí)(Primitive Obsession)

          認(rèn)為基本類型一定更加簡單,偏執(zhí)的使用大量的基本類型而不去定義應(yīng)有的結(jié)構(gòu)

          不可替代寫法:

          class Price {
            constructor(name, money) {
              this.name = name;
              this.money = money;
            }
            get name() {
              return name;
            }
            get count() {
              return parseFloat(this.money.slice(1));
            }
            get current() {
              return this.money.slice(01);
            }
            get unit() {
              switch (this.money.slice(01)) {
                case '¥':
                  return 'CNY';
                case '$':
                  return 'USD';
                case 'k':
                  return 'HKD';
              }
            }
            calcPrice() {
              // todo: 金額換算
            }
          }
          const myPrice = new Price("罐頭""$30")

          偏執(zhí)地使用字符串基本類型定義money,表面是Price的類,但在里面充斥著大量的money的數(shù)據(jù)處理。

          正常寫法:

          class Money {
            constructor(value) {
              this.value = value;
            }
            get count() {
              return parseFloat(this.value.slice(1));
            }
            get current() {
              return this.value.slice(01);
            }
            get unit() {
              switch (this.value.slice(01)) {
                case '¥':
                  return 'CNY';
                case '$':
                  return 'USD';
                case 'k':
                  return 'HKD';
              }
            }
          }
          class Price {
            constructor(name, money) {
              this.name = name;
              this.money = new Money(money);
            }
            get name() {
              return name;
            }
            calcPrice() {
              // todo: 金額換算
            }
          }
          const myPrice = new Price("罐頭""$20")

          money中存在著大量的數(shù)據(jù)處理,應(yīng)為期單獨(dú)建立個(gè)對象來作為它的類型。

          十、重復(fù)的switch(Repeated Switches)

          大量使用重復(fù)邏輯的switch,這樣的代碼是臃腫且脆弱的。

          不可替代寫法:

          class Money {
            constructor(value) {
              this.value = value;
            }
            get count() {
              return parseFloat(this.value.slice(1));
            }
            get current() {
              return this.value.slice(01);
            }
            get unit() {
              switch (this.current) {
                case '¥':
                  return 'CNY';
                case '$':
                  return 'USD';
                case 'k':
                  return 'HKD';
              }
            }
            get suffix() {
              switch (this.current) {
                case '¥':
                  return '元';
                case '$':
                  return '美元';
                case 'k':
                  return '港幣';
              }
            }
            get currentCount() {
              switch (this.current) {
                case '¥':
                  return this.count;
                case '$':
                  return this.count * 7;
                case 'k':
                  return this.count * 0.8;
              }
            }
          }

          大量相同邏輯的switch,若想增加一個(gè)判斷項(xiàng),需找到所有switch項(xiàng)進(jìn)行修改,一不注意則會遺漏,引發(fā)bug

          正常寫法:

          class Money {
            constructor(value) {
              this.value = value;
            }
            get count() {
              return parseFloat(this.value.slice(1));
            }
            get current() {
              return this.value.slice(01);
            }
          }
          class cnyMoney extends Money {
            constructor(props) {
              super(props);
            }
            get unit() {
              return 'CNY';
            }
            get suffix() {
              return '元';
            }
            get currentCount() {
              return this.count;
            }
          }
          class usdMoney extends Money {
            constructor(props) {
              super(props);
            }
            get unit() {
              return 'USD';
            }
            get suffix() {
              return '美元';
            }
            get currentCount() {
              return this.count * 7;
            }
          }
          class hkdMoney extends Money {
            constructor(props) {
              super(props);
            }
            get unit() {
              return 'HKD';
            }
            get suffix() {
              return '港幣';
            }
            get currentCount() {
              return this.count * 0.8;
            }
          }

          每一個(gè)分支項(xiàng)專注于自身的變化,修改時(shí)不會擔(dān)心某處遺漏。

          原文地址: https://juejin.cn/post/7126888773647876110#heading-


          瀏覽 33
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(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>
                  大香蕉在线视频精品视频 | 人成黄色视频 | 国产色综合视频 | 人人人人人人人人操 | 新超碰99|