成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

【前端】重構,有品位的代碼 05── 搬移特性

開發 前端
在本文中,主要介紹了搬移字段、搬移函數等搬移手段,也有單獨對語句搬移、調整順序的,也可以調整代碼的位置,對循環進行拆分、使用管道替換等方法。

[[408550]]

寫在前面

本文是《重構,有品位的代碼》系列第五篇文章,前面文章主要介紹的重構手法是關于如何新建、移除或重命名程序的元素。當然,不只是只有這些手法,還有類型的重構也是很重要的,主要是在不同上下文間搬移元素。可以通過搬移函數手法在類與其他模塊之間搬移函數,同樣的也有搬移字段手法,還有其它手法將在本文中將逐一介紹...

前情回顧:

  • 《重構,有品位的代碼 01──走上重構之道》
  • 《重構,有品位的代碼 02──構建測試體系》
  • 《重構,有品位的代碼 03──常用重構手法》
  • 《重構,有品位的代碼 04──封裝》

常見的搬移特性手法

在平時開發中,經常會在代碼中使用到搬移特性,但是并不知道是做了什么搬移特性,現在我們將常用的搬移特性手法進行總結如下:

  • 搬移函數
  • 搬移字段
  • 搬移語句到函數
  • 搬移語句到使用者
  • 以函數調用取代內聯代碼
  • 移動語句
  • 拆分循環
  • 以管道取代循環
  • 移除死代碼

1. 搬移函數

模塊化能夠確保我們的代碼塊間的聯系易于查找、直觀易懂,能夠保證相互關聯的軟件要素集中在一塊,便于我們理解和管理。與此同時,隨著對代碼的理解加深,了解到那些軟件要素如何組織最為恰當,此時需要通過不斷地搬移元素進行重新模塊化。

函數是存活在上下文中的,這個上下文可能是全局的,也有可能是當前所在模塊進行提供的。而類即為主要的模塊化手段,作為函數的上下文,此外通過函數嵌套的方式,外層函數也可為內層函數提供上下文。簡而言之,模塊可以為函數提供存活的上下文環境。

由于在某些代碼頻繁引用其他上下文中的元素,即與其他上下文的元素關系緊密,而對于自身上下文中的元素關心甚少,此時就可以考慮將聯系密切的元素進行歸納,取得更好的封裝效果。那么有以下情況,你可以進行搬移函數的操作:

  • 某段代碼需要頻繁調用別處函數
  • 在函數內部定義幫助函數在別處也有調用
  • 在類中定義函數

通常的,首先檢查函數在當前上下文中引用的所有程序元素(包括變量和函數),考慮是否需要將它們進行搬移,并對待搬移函數是否具有多態性進行檢查。將函數復制一份到目標上下文中,調整函數使得適應新的上下文。執行靜態檢查,設法從源上下文中正確引用目標函數,修改源函數,使之成為一個純委托函數。

原始代碼:

  1. class Account{ 
  2.   constructor(){ 
  3.     .... 
  4.   } 
  5.   get bankCharge(){ 
  6.     let result = 4.5; 
  7.     if(this._daysOverdrawn> 0) result += this.overdraftCharge; 
  8.   } 
  9.    
  10.   get overdraftCharge(){ 
  11.     if(this.type.isPremium){ 
  12.       const basecharge = 10; 
  13.       if(this.dayOverdrawn <= 7){ 
  14.         return baseCharge; 
  15.       }else
  16.         return baseCharge + (this.daysOverdrawn - 7) * 0.85; 
  17.       } 
  18.     }else
  19.       return this.daysOverdrawn * 1.75; 
  20.     } 
  21.   } 

重構代碼:

  1. class Account{ 
  2.   constructor(){ 
  3.     ... 
  4.   } 
  5.   get bankcharge(){ 
  6.     let result = 4.5; 
  7.     if(this._daysOverdrawn> 0) result += this.overdraftCharge; 
  8.   } 
  9.   get overdraftCharge(){ 
  10.     return this.Type.overdraftCharge(this); 
  11.   } 
  12.  
  13. class AccountType{ 
  14.   constructor(){ 
  15.     ... 
  16.   } 
  17.   overdraftCharge(account){ 
  18.     if(this.isPremium){ 
  19.       const basecharge = 10; 
  20.       if(account.dayOverdrawn <= 7){ 
  21.         return baseCharge; 
  22.       }else
  23.         return baseCharge + (account.daysOverdrawn - 7) * 0.85; 
  24.       } 
  25.     }else
  26.       return account.daysOverdrawn * 1.75; 
  27.     } 
  28.   } 

2. 搬移字段

在開發中你是否會遇到一些糟糕的代碼,使用了糟糕的數據結構,代碼的邏輯并不清晰條理,更多的是各種糾纏不清,代碼很多令人費解的無用代碼。因此,通常可以做些預先的設計,設法獲取最恰當的數據結構,而具備驅動設計方面的經驗和知識,將有助于你設計數據結構。

當然,即使經驗豐富、技能熟練,也會在設計數據結構的時候犯錯,但是隨著對問題理解的深入,對業務邏輯的熟悉,便會考慮到更深更全面。在過程中發現數據結構不適應需求,便要及時進行修繕,如果容許瑕疵存在便會導致代碼復雜化,問題累積。

在你每次進行調用函數時,在傳入一個參數時,總是需要伴隨另外的字段作為參數傳入,即修改一條記錄同時需要修改另一條記錄,那么意味著此處的字段位置放置錯誤。另外的,假設你更新某個字段,同時需要在多個結構中做出改變,那么就意味著你需要將此字段進行正確的搬移。

具體的,確保源字段已經進行良好封裝,在目標對象上創建字段(及對應的訪問函數)并執行靜態檢查,確保源對象里能夠正常引用目標對象,即調整源對象的訪問函數能夠使用目標對象的字段。最后,移除源對象上的字段。

原始代碼:

  1. class User
  2.   constructor(name,age,getName){ 
  3.     this._getName = getName; 
  4.     this._age = age; 
  5.     this._name = name
  6.   } 
  7.   get getName(){ 
  8.     return this._getName; 
  9.   } 
  10.  
  11. class UserType{ 
  12.   constructor(firstName){ 
  13.     this._firstName = firstName; 
  14.   } 

重構代碼:

  1. class User
  2.   constructor(age,name){ 
  3.     this._age = age; 
  4.     this._name = name
  5.   } 
  6.   get getName(){ 
  7.     return this._name.getName; 
  8.   } 
  9.  
  10. class UserType{ 
  11.   constructor(firstName,getName){ 
  12.     this._firstName = firstName; 
  13.     this._getName = getName; 
  14.   } 
  15.   get getName(){ 
  16.     return this._getName; 
  17.   } 

3. 搬移語句到函數

在重構代碼時有幾條黃金準則,其中最重要的就是要“消除重復”代碼,對重復語句進行抽象到函數中,通過調用函數來實現復雜代碼的運行。

4. 搬移語句到調用者

作為搬磚碼農的指責就是設計結構一致、抽象合宜的程序,而函數就是抽象的制勝法寶。當然所有的手段都并非放之四海而皆準的法則,隨著系統能力的演變,最初設計的抽象邊界逐漸向外擴散變得模糊,從原先單獨整體、聚焦唯一點,分化成多個不同關注點。

而函數邊界發生偏移,意味著之前多個地方調用的行為,現在需要會在不同點表現出不同的行為。這樣,我們可以把不同表現行為從函數中挪出,將其搬移到調用處。

  1. printHtml(outData,onData.html); 
  2.  
  3. function printHtml(outData,html){ 
  4.   outData.write(`<p>title:${html.title}</p>`); 
  5.   outData.write(`<p>content:${html.content}</p>`); 

即:

  1. printHtml(outData,onData.html); 
  2. outData.write(`<p>content:${onData.html.content}</p>`); 
  3.  
  4. function printHtml(outData,html){ 
  5.   outData.write(`<p>title:${html.title}</p>`); 
  6.    

5. 以函數調用取代內聯代碼

使用函數可以將相關行為進行打包,提升代碼的表達能力,清晰的解釋代碼的用途和作用,有助于消除重復的代碼。如果某段內聯代碼是對已有函數進行重復,那么可以使用一個函數調用來取代內聯代碼,可以實現業務邏輯的抽象。

  1. let flag = false
  2. for(const color of colors){ 
  3.   if(color === "yellow") flag = true

即:

  1. let flag = colors.includes("yellow"); 

6. 移動語句

如果有幾行代碼使用了相同的數據結構,那么可以使其關聯使用,使得代碼更易理解,而不是夾在其他數據結構中間。那么在我們寫完代碼后,需要進行審讀,將關聯性強的代碼移動語句進行聚集。通常,移動語句作為其他重構代碼的先提重構手段。

  1. const pricingPlan = rePricingPlan(); 
  2. const order = reOrder(); 
  3. let charge; 
  4. const chargePerUnit = ricingPlan.uint; 

重構代碼:

  1. const pricingPlan = rePricingPlan(); 
  2. const chargePerUnit = ricingPlan.uint; 
  3. const order = reOrder(); 
  4. let charge; 

7. 拆分循環

在常規的開發中,會在一次循環中做多件事情,意圖讓其避免過高的時間復雜度。有的時候,在一次循環中代碼過多、邏輯混亂,反而不便于我們日常理解。因此可以根據情況合理拆分循環,使其每次循環只做一件事情,更便于閱讀使用。

  1. let averagePrice = 0; 
  2. let totalCount = 0; 
  3. for(const p in goods){ 
  4.   averagePrice += p.price; 
  5.   totalCount += p.count
  6. averagePrice = averagePrice / totalCount; 

重構代碼:

  1. let averagePrice = 0; 
  2. for(const p in goods){ 
  3.   averagePrice += p.price; 
  4. let totalCount = 0; 
  5. for(const p in goods){ 
  6.   totalCount += p.count
  7.  
  8. averagePrice = averagePrice / totalCount; 

是不是看起來有點傻,當你在復雜代碼中閱讀會發現很清晰。

8. 以管道取代循環

在過去進行數組、對象遍歷時,通常做法是使用循環進行迭代,當然也可以使用更好的語言結構———”集合管道“來處理迭代(map和filter等)。集合管道允許使用一組運算來描述集合迭代過程,其中每種運算都是一個集合。

通常做法:創建一個用于存放參與循環過程的集合的新變量,從c循環頂部開始,將循環內的每塊行為依次搬移。在創建的集合變量中用管道運算進行替換,直到循環內的全部行為進行搬移完畢,最后將循環進行刪除。

  1. const users = []; 
  2. for(const item in arrs){ 
  3.   if(item.age === 20) users.push(item.name); 
  4.  
  5. //重構代碼 
  6. const users = arrs 
  7. .filter(item=>item.age === 20) 
  8. .map(item=>item.name); 

9. 移除死代碼

在將項目部署在生產環境中,可能會因為代碼量太大而造成更大的內存開銷,無用代碼會拖累系統的運行速度,導致項目進程緩慢。當然,多數的現在編譯器會自動將無用代碼進行移除,但是在你閱讀理解代碼邏輯和原理時,會讓你花費時間去思索,耗費精力。在代碼不再使用時,應當立即刪除,當你突然又想使用時可以通過版本控制回滾。

  1. if(false){ 
  2.   ... 

這是一句無用代碼,應當立刻刪除。

小結

在本文中,主要介紹了搬移字段、搬移函數等搬移手段,也有單獨對語句搬移、調整順序的,也可以調整代碼的位置,對循環進行拆分、使用管道替換等方法。

 

責任編輯:姜華 來源: 前端萬有引力
相關推薦

2021-08-03 08:13:48

重構API代碼

2021-07-03 12:28:30

前端數據代碼

2021-07-10 14:22:24

前端代碼條件邏輯

2013-09-16 10:57:59

蘋果世界

2020-12-08 06:20:49

前端重構Vue

2013-06-09 10:37:14

架構框架

2024-09-05 10:17:34

2022-08-08 13:24:28

整潔架構架構前端

2012-07-27 10:30:12

重構

2011-08-16 09:47:58

編程

2019-02-18 16:21:47

華為代碼重構

2021-08-01 22:35:16

Vscode開發編輯器

2023-10-20 08:04:34

系統重構實踐

2023-02-27 07:40:00

系統重構前端

2022-12-26 00:02:24

重構代碼軟件

2019-04-03 08:10:17

代碼架構信息

2024-02-22 10:27:00

Python開發

2010-11-25 13:53:13

VPNDVPN

2018-04-25 10:03:28

前端重構Javascript

2020-05-19 08:06:57

代碼重構代碼開發
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一级黄a | 午夜久久久久久久久久一区二区 | 欧美日韩在线成人 | 91啪亚洲精品 | 久久成人午夜 | 一区二区手机在线 | 91色在线| 中文字幕日韩专区 | 色网站视频 | 日韩电影中文字幕 | 国产精品视频免费看 | 一区二区免费在线视频 | 成人视屏在线观看 | 一区不卡在线观看 | 亚洲视频一区二区三区四区 | 久久久久久毛片免费观看 | 欧美激情va永久在线播放 | 日本羞羞影院 | 午夜在线免费观看视频 | 欧美日韩一区二区视频在线观看 | 91精品国产综合久久精品 | 黄视频在线网站 | 成年人网站国产 | 中文字幕91 | 日韩二区 | 国产精品免费一区二区三区四区 | 国产一区二区在线免费播放 | av中文字幕在线 | 久久久久一区 | 一区二区中文 | 日日想夜夜操 | 欧美激情视频一区二区三区免费 | 91国产在线播放 | 日韩中文一区二区三区 | 欧美8一10sex性hd | 91视频18 | 免费观看一级特黄欧美大片 | 一区二区三区高清 | 在线观看黄色电影 | 久久激情网| 在线播放中文字幕 |