품질을 향상시키기 위해 코드를 미니 리팩터링하는 것이 유용한가요? 아니면 큰 이점없이 "이동하는 코드"입니까?


12

한 곳에서 "모든 것"을 수행하는 모 놀리 식 코드를 발견했습니다. 데이터베이스에서 데이터를로드하고 HTML 마크 업을 표시하며 라우터 / 컨트롤러 / 액션으로 작동합니다. SRP 이동 데이터베이스 코드를 자체 파일에 적용하기 시작하여 더 나은 이름 지정 기능을 제공했지만 모두 좋아 보였지만 왜 내가 이것을하는지에 대한 의문이 생겼습니다.

왜 리팩터링해야합니까? 목적은 무엇입니까? 쓸모 없습니까? 이점은 무엇입니까? 필자는 대부분 모 놀리 식 파일을 그대로두고 있지만 일부 작업을 수행 해야하는 영역과 관련된 작은 부분 만 리팩토링했습니다.

원본 코드 :

구체적인 예제를 제공하기 위해이 코드 스 니펫을 발견했습니다. 알려진 제품 ID 또는 사용자가 선택한 버전 ID로 제품 사양을로드합니다.

if ($verid)
    $sql1 = "SELECT * FROM product_spec WHERE id = " . clean_input($verid);
else
    $sql1 = "SELECT * FROM product_spec WHERE product_id = " . clean_input($productid) ;
$result1 = query($sql1);
$row1 = fetch_array($result1);
/* html markup follows */

리팩토링 :

이 특정 코드 부분을 변경해야하는 작업을 수행하고 있으므로 리포지토리 패턴을 사용하도록 변경하고 객체 지향 MySQL 기능을 사용하도록 업그레이드했습니다.

//some implementation details omitted 
$this->repository = new SpecRepository($mysql);
if ($verid)
    $row1 = $this->repository->getSpecByVersion($verid);
else 
    $row1 = $this->repository->getSpecByProductId($productid);
/* html markup follows to be refactored or left alone till another time*/

//added new class:
class SpecRepository extends MySqlRepository
{

    function getSpecByVersion(int $verid)
    {
        return $this->getMySql()->paramQuery("
            SELECT * FROM product_spec WHERE id = ?
        ", $verid)->getSingleArray();
    }

    function getSpecByProductId(int $productid)
    {
        return $this->getMySql()->paramQuery("
            SELECT * FROM product_spec WHERE product_id = ?
        ", $productid)->getSingleArray();
    }
}

내가해야합니까?

변경 사항을 되돌아 보면 코드는 여전히 기능적이지만 동일한 파일이지만 다른 파일, 다른 이름, 장소에 있으며 절차 적보다는 객체 지향 스타일을 사용합니다. 실제로 리팩토링 된 코드는 기능이 동일하지만 부풀어 오른 것처럼 보입니다.

나는 "리팩토링 이유를 모른다면하지 말아라"라고 대답 할 것으로 예상하고 아마 동의 할 것이다. 내 이유는 시간이 지남에 따라 코드 품질을 향상시키는 것입니다 (그리고 SRP 및 기타 원칙을 따르면 그렇게 할 수 있기를 바랍니다).

그 좋은 이유가 있습니까? 아니면 이런 식으로 "코드를 다시 정렬"하는 데 시간을 낭비하고 있습니까? 전반적으로 리팩토링은 솔직히 말해서 물을 밟는 것처럼 느껴집니다. 시간이 걸리고 SRP가 진행되는 한 더 "분리"됩니다. 그러나 좋은 의도에도 불구하고 놀라운 개선을하고있는 것 같지는 않습니다. 따라서 리팩터링하지 않고 코드를 이전에 그대로 두는 것이 가장 좋은지 토론합니다.

왜 처음에 리팩터링 했습니까?

필자의 경우 새로운 제품군에 새로운 기능을 추가하고 있으므로 유사한 제품군에 대한 기존 코드 구조를 따르거나 직접 작성해야합니다.


구약이지만 Select * from ..고려해야 할 것은 반 패턴으로 간주 될 수 있다는 것입니다. 참조 stackoverflow.com/q/3639861/31326
피터 M

1
@PeterM : ORM을 작성하지 않는 한이 경우 select *"모범 사례"가됩니다.
Robert Harvey

왜 의문을 제기하고 경우 @RobertHarvey에서 당신은 당신의 자신의 ORM을 작성 : D
피터 M

더 관련이없는 원인으로 리팩터링을 수행했습니다. 혜택이 비용을 능가하자마자 기술 부채를 줄이는 것이 좋습니다. 이것이 당신의 경우 인 것 같습니다. 문제는 코드가 여전히 예상대로 작동하는지 확인하기위한 올바른 테스트를 가지고 있습니까?
Laiv

1
신뢰성은 변경 가능성과 관련된 유지 관리 성이 아니라 IMO를 리팩토링 할 때 가장 중요한 측정 기준이어야합니다. 안정성을 개선하고 완벽하게 안정적이고 신뢰할 수 있으며 코드를 변경해야 할 이유가 거의 없기 때문에 유지 관리 비용이 거의 들지 않습니다. 가능한 한 쉽게 변경하려고 시도하는 대신 변경 사유를 줄이십시오. 전자를 찾는 것도 후자 중 일부를주는 경향이 있습니다.

답변:


13

당신이 준 구체적인 예에서, 리팩토링은 적어도 아직 필요하지 않았을 수도 있습니다. 그러나 미래에는 더 복잡한 코드가 잠재적으로 더 길고 지루한 리팩토링으로 이어질 가능성이 있음을 알았으므로 지금 이니셔티브를 취해 정리했습니다.

또한 여기에서 얻을 수있는 이점은 적어도 내 관점에서 코드 기반을 모르는 사람으로 이해하기 쉬운 코드 였다고 말할 수 있습니다.


일반적으로 :

리팩토링을 통해 다른 개발자가 코드를 쉽게 이해할 수 있습니까?

리팩토링으로 코드를보다 쉽게 ​​향상시킬 수 있습니까?

리팩토링으로 코드를보다 쉽게 ​​관리 할 수 ​​있습니까?

리팩토링으로 디버깅하기가 더 쉬워 집니까?

이 중 하나에 대한 대답이 "예"라면 그만한 가치가 있었고, 단지 "이동하는 코드?"

이 모든 것에 대한 대답이 "아니오"라면 리팩토링 할 필요가 없었을 것입니다.

코드베이스의 최종 크기는 (일부 리팩토링 중복 코드를 간소화하여 코드베이스를 축소 할 수 있지만) 명 LoC의 측면에서 더 클 수 있지만, 다른 이익이있는 경우 그 요인이어야한다.


9

모놀리스를 분해하는 경우 리팩토링이 팽창합니다.

그러나 이미 이점을 발견했습니다.

"제 경우에는 새로운 제품군에 새로운 기능을 추가하고 있습니다."

방해하지 않고 모놀리스에 기능을 매우 쉽게 추가 할 수 없습니다.

동일한 코드가 데이터를 가져오고 마크 업을 수행한다고 말했습니다. 특정 조건에서 표시하기 위해 선택하고 조작하는 열을 변경하고 싶을 때까지 좋습니다. 갑자기 어떤 경우에는 마크 업 코드가 작동을 멈추고 리팩토링 해야합니다 .


예, 그러나 새로운 기능을 위해 모노리스에 계속 추가 할 수 있습니다. :) 새 if/else블록을 추가하고 원래 스타일의 코드를 따라 SQL 문을 추가 한 다음 동일한 모노리스 파일에 새로운 HTML 마크 업을 넣습니다. 그리고 열을 변경하려면 SQL 줄을 수용하는 if / else 블록을 찾고 해당 파일을 손상시키지 않고 열을 변경하도록 SQL을 편집하십시오.
Dennis

리팩토링 된 접근 방식을 사용하면 먼저 모노리스의 if / else 블록으로 이동하여 SQL을 변경하기 위해 별도의 저장소 파일로 이동해야한다는 것을 알 수 있습니다. 또는 최근에 그 모놀리스를 연구했다면 모놀리스를 우회하여 대신 저장소 파일로 바로 들어가는 것을 알고 있습니다. 또는 특정 SQL에 대한 코드베이스를 검색 한 경우 검색을 통해 단일 저장소를 우회하여 새 리포지토리 파일도 만들 수 있습니다.
Dennis

2

그 프로젝트로 몇 달 또는 몇 년을 일해야한다는 것을 알고 있다면 리팩토링을 고려하십시오. 여기저기서 변경해야한다면 코드를 옮기려는 충동에 저항하는 것보다.

리팩토링을 수행하는 가장 좋은 방법은 일종의 자동 테스트가있는 기본 코드가있을 때입니다. 그럼에도 불구하고 이전과 같이 작동하는지 확인하기 위해 변경 한 내용에 매우주의해야합니다. 작업하려는 버그 이외의 영역에서 버그를 전달하면 곧 신뢰를 잃게됩니다.

다음과 같은 이유로 리팩토링을 중요하게 생각합니다.

  • 코드를 더 잘 이해합니다
  • 중복 된 코드를 제거하므로 한 곳에 버그가 있으면 코드를 복사하여 붙여 넣은 곳을 모두 사냥 할 필요가 없습니다.
  • 나는 잘 정의 된 역할을 가진 클래스를 만듭니다. 예를 들어 동일한 저장소를 재사용하여 HTML 페이지, XML 피드 또는 백그라운드 작업을 수화 할 수 있습니다. 데이터베이스 액세스 코드가 HTML 클래스에만있는 경우에는 불가능했을 것입니다.
  • 변수, 메소드, 클래스, 모듈, 폴더가 현재 현실과 일치하지 않으면 이름을 바꿉니다. I comment변수 이름, 메소드 이름을 통해 코드
  • 단위 테스트와 리팩토링을 조합하여 복잡한 버그를 해결합니다.
  • 전체 모듈, 패키지를 교체 할 수있는 유연성이 있습니다. 현재 ORM이 오래되었거나 버그가 있거나 유지 관리되지 않은 경우 프로젝트 전체에 퍼져 있지 않으면 교체하기가 더 쉽습니다.
  • 고객에게 제안 할 새로운 기능이나 개선 사항을 발견했습니다.
  • 재사용 가능한 구성 요소를 만들었습니다. 이는 해당 프로젝트에서 수행 한 작업이 다른 클라이언트 / 프로젝트에 재사용 될 수 있기 때문에 가장 큰 이점 중 하나였습니다.
  • 나는 종종 가장 멍청하고 하드 코딩 된 엉뚱한 솔루션으로 시작하고 나중에 더 배우면 리팩터링합니다. 이 나중의 순간은 오늘 일 수도 있고 며칠 후에있을 수도 있습니다. architect솔루션에 너무 많은 시간을 보내고 싶지 않습니다 . 이것은 코드를 앞뒤로 다시 쓰는 동안 작성합니다.

완벽한 세계에서 리팩토링은 단위 테스트, 통합 테스트 등으로 확인해야합니다. 없는 경우 추가하십시오. 또한 일부 IDE가 많은 도움이 될 수 있습니다. 나는 보통 돈이 많은 플러그인을 사용합니다. 리팩토링에 거의 시간을 투자하지 않고 매우 효율적으로 작업하고 싶습니다.

나는 또한 버그를 소개했다. 일부 QA가 왜 요구하는지 알 수 있습니다. 이것이 are you guys doing refactoring? because everything stopped working!팀이 감수해야 할 위험이므로 항상 투명해야합니다.

몇 년 동안 나는 지속적인 리팩토링이 생산성을 향상시키는 것을 발견했다. 새로운 기능을 추가하기가 훨씬 쉬워졌습니다. 또한 코드 기반이 제품의 진화에 맞지 않을 때 종종 발생했던 것처럼 큰 재 구축에는 전체적인 재 작성이 필요하지 않았습니다. 또한 재미있다.


이것은 다운 투표에 매우 가깝습니다- '컴퓨터 프로그래머'에는 'I'가 없습니다. '나'는 '나'(투표)입니까, 아니면 개발자가 현재와 미래에 코드 작업을 의미합니까?
mattnz

나도 알아 차 렸지만 말로 표현했다. 또한 몇 년 동안 솔로 개발자로 일 했으며이 답변을 쓸 때 주로 그 경험을 반복했습니다. 나는 대체 할 수 I와 함께 to생각.
Adrian Iftode

1

당신이 스스로에게 물어봐야 할 질문은 그렇게 많은 것이 아니라고 생각합니다. "이익이 있습니까?" "누가이 일에 돈을 지불 할까?"

우리는 모두 끝날까지 인식 된 혜택에 대해 논쟁 할 수 있지만, 그러한 혜택을 믿고 고객이하지 말아야 할 변경에 대해 지불 할만큼의 가치가있는 고객이없는 한.

개발자 팀 어딘가에서 코드를보고 리팩터링하여 '더 나은'것으로 만드는 것은 너무 쉽습니다. 그러나 제품이 이미 작동 할 때 '더 나은 코드'에 가치를 두는 것은 정말 어렵습니다.

'새로운 기능의 빠른 개발'과 같은 것들은 단지 비용이 절감되기 때문에 자르지 않습니다. 판매를 생성해야합니다.


1

제 생각에는 리팩토링은 좋은 투자입니다.

그렇지 않으면 곧 기술 부채가 발생합니다 (해결되지 않은 문제, 특정 조건에서만 작동하는 잘못된 코드 등). 소프트웨어를 더 이상 유지 보수 할 수 없을 때까지 기술 부채가 점점 커질 것입니다.

그러나 리팩토링 작업을하려면 테스트에도 투자해야합니다. 자동화 된 테스트를 작성해야하며 이상적으로는 단위 테스트 및 통합 테스트가 있어야합니다. 이는 기존 코드를 위반하지 않도록 방지합니다.

상사 나 동료를 설득해야하는 경우 민첩한 방법 (예 : SCRUM) 및 테스트 중심 개발에 대한 일부 책을 읽어야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.