2021년 11월 18일 목요일

[冊] 리팩터링

 리팩터링 원칙 > 리팩터링에 대한 저자의 전반적인 견해


리팩터링 정의

리팩터링이란? 소프트웨어의 겉보기 동작은 그대로 유지한 채, 고드를 이해하고 수정하기 쉽도록

내부 구조를 변경하는 기법

>> 리펙터링하다 코드가 깨졌다라고 한다면 그것은 리펙터링이 아니다

restructuring > 재구성

코드 베이스를 정리하거나 구조를 바꾸는 모든 작업

refactoring > 모든 restructuring 중에서 도중에 중단되더라도 동작이 유지되는 것


리팩터링을 하는 이유

1. 소프트웨어 설계가 좋아진다.

2. 소프트웨어를 이해하기 쉬워진다.

3. 버그를 쉽게 찾을 수 있다.

결론 : 프로그래밍 속도를 높일 수 있다.


리팩터링과 성능

리팩터링을 하면서 성능이 저하되면 안된다.

*성능 이슈도 같이 파악할 것


먼저 성능보다 알기 쉽고, 정렬된 코드를 작성한다.

성능 최적화에 대해 프로파일러를 사용하여 분석한다.

로직 중에 소요 시간을 측정하여 개선한다.

(코드 중에 시간 성능에 따라 좋은 코드가 있는데, 해당 부분도 정리할듯)

 - 이 부분을 개선


 YAGNI에 대하여 서술하세요

=> You Aren't Going to Neet It

 - 코딩을 시작하기 전에 아키텍처를 확정해야 한다.

아키텍처를 확정하지 않으면, 요구사항 사전 파악이 불가능하다.

  - 유연성 메커니즘을 심어두면, 오히려 대응 능력을 저해할 수 있다.

이를 YAGNI라고 한다.

=> 추측하지 말고 현재 요구사항에 충실하여 충족시키도록 해야 한다.

=> 대신에 이에 대해 최대한 잘 해결되도록 설계해야 한다.

=> 나중에 이에 대해 더 잘 이해하게 되면, 리팩터링을 활용하여 바꾸어야 한다.


이것은 선제적 아키텍처에 소홀해진다는 의미가 아니다.

이미 알고 있는 부분은 최대한 신경 써서 사전에 준비하는 것이 좋으나,

모르는 부분을 미리 대비하기 보다는, 이해하고 나서 반영하는 것이 효율적이다.


코드에서 악취가 난다?

변수 명의 잘못

=> 변수 명이 영단어 단수 명사로 표기되어야 한다. 3~4자로 약축어를 

사용하는 편이 좋은데, 해당 부분 역시 싸이트 검색을 활용하는 것이 바람직하다.-

=>함수 형태를 활용하여 리팩토링하고, 쪼개기를 하는 것이 좋다.


리팩토링의 정의

리팩토링(Refactoring) - 소프트웨어를 보다 쉽게 이해할 수 있고, 적은 비용으로 수정할 수 있도록

겉으로 보이는 동작의 변화 없이 내부 구조를 변경하는 것

리랙토링 하다(Refactoring) - 일련의 리펙토링을 적용하여 겉으로 보이는 동작의 변화 없이 소프트웨어 구조를 바꾸다.

첫째 리팩토링의 목적은 소프트웨어를 보다 이해하기 쉽고, 수정하기 쉽도록 만드는 것이다

둘째 리팩토링은 겉으로 보이는 소프트웨어의 기능을 변경하지 않는다는 것이다


두 개의 모자

두가지 구별된 작업(기능 추가와 리팩토링)을 위해 시간을 나눠야 한다

기능을 추가할 때는 기존 코드를 건드려서는 안되고 단지 새로운 기능만 추가해야 한다

리팩토링을 할 때는 기능을 추가해서는 안되고 단지 코드의 구조에만 신경써야 한다.


왜 리팩토링을 해야 하는가?

리팩토링은 소프트웨어의 디자인을 개선 시킨다.

리팩토링은 소프트웨어를 더 이해하기 쉽게 만든다.

리팩토링은 버그를 찾도록 도와준다.

리팩토링은 프로그램을 빨리 작성하도록 도와준다.


언제 리팩토링을 하는가?

삼진규칙 - 3번 중복되면 그때 리팩토링을 한다.

기능을 추가할 때 리팩토링을 하라

버그를 수정할 때 리팩토링을 하라

코드검토(code review)를 할 때 리팩토링을 하라

관리자에게는 뭐라 말해야 하나?

리팩토링을 할 때의 문제

데이터베이스

인터페이스 변경

리팩토링이 어려운 디자인 변경

언제 리팩토링을 하지 말아야 하는가?


코드속 나쁜 냄새

이제 리팩토링이 어떻게 돌아가는지 잘 알게 되었을 것이다 리팩토링을 언제 시작하고 언제 끝낼지를 결정하는 것은 리팩토링을 어떤 절차에 따라 해야 하는지를 아는 만큼이나 중요하다 인스턴스 변수 하나 삭제하거나 클래스 구조를 만드는 것에 대해 설명하는 것은 쉽다. 프로그램 미학(aesthetics) 같은 모호한 개념에 호소하기 보다는 좀 더 구체적인 것을 원한다.


Kent Beck을 방문했을때 리팩토링을 필요한 시점에 대한 생각을 냄새의 관점에서 설명했다. 냄새 - 정확한 지점을 집어내기 보다는 뭉뚱그려서 찾아냅니다


중복된 코드(Duplicated Code)

한 곳 이상에서 중복된 코드 구조가 나타난다면, 그것을 합쳐서 프로그램을 개선할 수 있다.


한 클래스의 서로 다른 두 메소드 안에 같은 코드가 있는 경우

Extract Method - 뽑아낸 메소드를 두 곳에서 호출하도록 하는 것


동일한 수퍼 클래스를 갖는 두 서브 클래스에서 같은 코드가 있는 경우

양쪽 클래스에서 Extract Method 사용한 다음 Pull Up Method 사용한다


코드가 비슷하기는 하지만 같지는 않다면

비슷한 부분과 서로 다른 부분을 분리하기 위해 Extract Method 사용 후 Form Template Method 사용할 수 있는지 살펴본다


같은 작업을 하지만 다른 알고리즘을 사용한다면

두 알고리즘 중 더 명확한 것을 선택한 다음 Substitute Algorithm을 사용할 수 있다.


서로 관계 없는 두 클래스에서 중복된 코드가 있는 경우

한쪽 클래스에서 Extract Class를 사용한 다음 양쪽에서 이 새로운 클래스를 사용하도록 하는 것 고려

메소드가 클래스 중 하나에 포함되어 있고 다른 클래스에서 호출

세번째 클래스에 속하는 그 메소드가 원래 두 클래스에서 참조되어야 하는 경우


긴 메소드(Long Method)

우리가 따르는 방법은 어떤것에 대해서 주석을 달아야 할 필요를 느낄 때마다 메소드를 작성하는 것이다

메소드의 길이가 아니라 메소드가 하는 일과 일을 처리하는 방법 사이의 의미적 거리(semantic distance)


대부분의 경우 메소드의 길이를 줄이가 위해 해야 하는 경우

Extract Method 사용하자


메소드에 파라미터와 임시변수가 많다면

임시변수는 Replace Temp with Query를 사용할 수 있다

긴 파라미터 리스트는 Introduce Parameter Object, Preserve Whole Object 사용할 수 있다.


여전히 임시변수와 파라미터가 많다면

Replace Method with Method Object라는 중장비를 사용하자


뽑아낼 코드 덩어리의 식별은 주석을 찾는 것이다.조건문과 루프 또한 메소드 추출이 필요하다는 신호를 준다.


조건식을 다루기 위해서는

Decompose Conditional 사용한다.


루프의 경우는 루프와 그 안의 코드를 추출하여 하나의 메소드로 만든다

댓글 없음:

댓글 쓰기