리팩토링으로 코드를 훈련하는 방법(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 }

이해하기 매우 어려운 문제에 표시된 것과 같은 큰 표현식의 경우 각 표현식에 대해 다른 변수를 생성할 수 있습니다. 코드를 더 읽기 쉽게 만듭니다. 그러나 이 방법은 주의해서 적용해야 합니다. 그러나 자체 단점이 있습니다. 코드는 문제의 경우가 아닌 조건이 false인 경우에도 실행됩니다.

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

메서드가 값을 반환하고 개체를 변경하는 경우 두 메서드를 분할합니다. 하나는 수정용이고 다른 하나는 결과를 반환하기 위한 것입니다. 의도하지 않은 개체 수정 가능성을 제거합니다.