如何通過重構規範您的代碼(包括 PHP 示例)

已發表: 2021-06-22

像生活中的許多其他事情一樣,我們的代碼也需要一些紀律。 我很確定世界上沒有開發人員願意編寫不干淨的代碼。 但是,不干淨的代碼仍然存在。 它可能由多種原因引起 - 可能是由於業務壓力、缺乏文檔、團隊成員之間缺乏互動或開發人員無能。 需要採取適當的措施使代碼更清晰,並避免將來因此可能出現的問題。 幸運的是,我們可以通過一種規範的技術來解決這些問題,以重構稱為Refactoring的代碼。

重構是一種改進現有程序源代碼的內部結構並保持其外部行為的技術。 這是一個循序漸進的過程來改進代碼,否則會花費我們大量的時間和精力。

代碼重構

不干淨代碼的缺點

通過添加新程序來擴大源代碼大小而不進行長時間的重構,使得代碼變得凌亂和不干淨。 這使得項目的維護和進一步開髮變得非常困難。 不干淨的代碼有很多缺點:

  1. 它增加了項目的維護成本。
  2. 添加新功能需要花費大量時間,有時甚至無法添加。
  3. 它減慢了向項目引入新人的速度。
  4. 它包含重複的代碼。
  5. 它沒有通過所有測試。

還有許多其他缺點,但這些問題會花費組織大量的金錢和時間。

乾淨代碼的優勢

乾淨和規範的代碼有其自身的優勢:

  1. 它不包含重複的代碼。
  2. 它通過了所有測試。
  3. 使代碼更具可讀性和更容易理解。
  4. 它使代碼更易於維護且成本更低。

乾淨代碼的優點有很多。 將凌亂的不干淨代碼變成更易於維護的干淨代碼的過程稱為重構過程。

重構過程

重構應該作為一系列小的改動來完成,每一個改動都會稍微改進現有的代碼,並允許程序繼續運行而不破壞它。 重構後,代碼應該比以前更乾淨。 如果它仍然不干淨,那麼重構就沒有意義了。 這只是時間和精力的損失。 在重構過程中不應添加新代碼以創建新功能。 它應該在重構後通過所有測試。

何時重構

在以下情況下應執行重構:

  • 向項目添加重複代碼。 因為重複的代碼很難維護,一個地方的更改可能需要許多其他地方的更新。
  • 添加一個功能。 重構使添加新功能變得更加容易。
  • 修復錯誤時,您應該重構,因為它會使錯誤自動發現。
  • 代碼審查是在將更改部署到生產之前重構代碼的最後階段。

處理代碼異味

代碼問題有時被稱為代碼異味。 這些是重構過程中解決的問題。 它們更容易找到和修復。

例如:

  • 很難使用的大型方法和類。
  • 面向對象編程概念的不完整或不正確的使用。
  • 難以添加任何更改的代碼。
  • 項目中重複和棄用的代碼。
  • 高度耦合的代碼。

重構技術

重構技術是重構代碼所採取的步驟。 一些重構技術是:

1.提取方法

// 問題

function printInvoice() { $this->printHeader(); // Print details. print("name: " . $this->name); print("amount " . $this->getPrice()); }

// 解決方案

function printInvoice() { $this->printBanner(); $this->printDetails($this->getPrice()); } function printDetails($price) { print("name: " . $this->name); print("amount " . $outstanding); }

如果您有可以分組的代碼片段,請為該部分代碼添加新方法並替換舊代碼。 它使代碼更加孤立並消除重複。

2. 提取變量

// 問題

if (($student->getMarksinMath() > 60) && ($student->getMarksInPhysics() > 60) && ($student->getMarksinChemistry() > 60) && $this->pass) { // do something }

// 解決方案

$mathResult = $student->getMarksinMath() > 60; $physicsResult = $student->getMarksinPhysics() > 60; $chemistryResult = $student->getMarksinChemistry() > 60; $hasPassed = $this->pass; if ($mathResult && $physicsResult && $chemistryResult && $hasPassed) { // do something }

對於問題中顯示的大型表達式,非常難以理解,可以為每個表達式創建不同的變量。 它使代碼更具可讀性。 但這種方法應謹慎應用。 但是,它有其自身的缺點。 即使條件為假,代碼也會執行,而問題並非如此。

3. 內聯方法

// 問題

function printResult() { return ($this->getResult()) ? “Pass” : “Fail”; } function getResult() { return $this->totalMarks > 300; }

// 解決方案

function getRating() { return ($this->totalMarks > 300) ? “Pass” : “Fail”; }

當方法體比較明顯時,使用這個技巧。 用方法內容替換方法並刪除方法。 它最大限度地減少了不需要的方法的數量。

4. 內聯溫度

// 問題

$mathMark = $student->getMathResult(); return $mathMark > 60;

// 解決方案

return $student->getMathResult() > 60;

如果有一個不需要的臨時變量只保存表達式結果,請刪除帶有表達式本身的變量。 它有助於擺脫不必要的變量。

5. 用對象替換數組

// 問題

$row = []; $row[0] = "Virat Kohli"; $row[1] = 70;

// 解決方案

$row = new Player(); $row->setName("Virat Kohli"); $row->setNumberofCentury(70);

如果有一個包含各種類型數據的數組,請將其替換為一個對象。 因為類的字段比具有各種類型數據的數組更容易記錄和維護。

6. 參數化方法

// 問題

function fivePercentRaise() { } function tenPercentRaise() { }

// 解決方案

function raise(percent) { }

如果多個方法對數據執行類似的操作,則將所有方法替換為一種方法並將數據作為參數傳遞。 它刪除了重複和冗餘的方法。

7. 將查詢與修飾符分開

// 問題

function getInterest() { $this->interestAmount = $this->principal * 10 / 100; return $this->interestAmount; }

// 解決方案

function setInterest() { $this->interestAmount = $this->principal * 10 / 100; } function getInterest() { return $this->interestAmount; }

如果一個方法正在返回值並更改對象,則拆分這兩個方法。 一個用於修改,另一個用於返回結果。 它消除了無意修改對象的機會。