리팩토링
2022.08.17 김천규
“컴퓨터가 이해할 수 있는 코드는 어느 바보나 다 짤 수 있다.
좋은 프로그래머는 사람이 이해할 수 있는 코드를 짠다.”
- 마틴 파울러( Martin Fowler)
리팩토링이란?
소프트웨어의 겉보기 동작은 그대로 유지한 채,
코드를 이해하고 수정하기 쉽도록
내부 구조를 변경하는 기법
리펙토링을 해야하는 이유 Why?
소프트웨어 설계가 좋아진다.
=> 소프트웨어를 이해하기 쉬워진다.
=> 버그를 쉽게 찾을 수 있다.
 프로그래밍 속도를 높일 수 있다.
대부분 개발보다 분석하는데 시간을 많이 투자함.
대부분 어쩌라고?
저는 이렇습니다.
• 전날 본인이 개발한 코드도 갸우뚱거림
• 남에게 코드 설명하기 힘들다.
• 기능 추가 및 수정할 때 생각하기 싫다 (머리 싸매고)
코드에 자신을 얽매이게 하지마
마틴 파울러( Martin Fowler)
사고의 전환: 개발 vs 리펙토링
리팩토링 과정
리팩토링 검증방식 = BlackBox
소프트웨어 설계의 원칙
• 구현에 드는 수고보다 유지 보수에 드는 수고를 줄이는 게 더 중요
• 유지 보수에 드는 수고는 시스템 복잡성에 비례
참고도서: 심플소프트웨어 (맥스 카넷-알렉산더 지음)
언제 해야할까? 리펙토링
1. 기능을 새로 추가하기 직전
2. 코드를 이해하기 어려울 때
3. 불필요한 코드를 발견 했을 때
4. 코드 리뷰
읽기 힘들다
복잡하다
복잡함의 기준?
하…
복잡성의 단서
• 약간의 꼼수를 써야만 코드가 잘 작동한다.
• 다른 개발자들이 코드 작동 방식을 계속 물어본다.
• 다른 개발자들이 코드를 잘못 사용해 버그가 계속 발생한다.
• 그 코드를 수정할 생각을 하면 두렵다.
• 관리자가 업무 하나에 여러 개발자를 붙이려 한다.
• 기능 추가 방법을 알아내기 어렵다.
• 그 코드에 어떤 사항을 구현하는 방법을 두고 자주 논쟁한다.
참고도서: 심플소프트웨어 (맥스 카넷-알렉산더 지음)
우리의 모습?
공감되지 않나요?
이러면 안됩니다..
왜 이럴까?
네이밍
네이밍
가장 적절한 명칭이 뭘까? 고민을 해야한다.
변수, 상수, 함수, 클래스, enum등
명칭에 대해 주석을 다는 것 =>
스스로가 부정확함을 알고 있다는 것
(예외. 특정 업무 용어, 영어 해석이 다의어가 되는 경우 등등)
네이밍: 의식의 흐름
user_name 변수인가보네?
UserName? 왜 첫글자가 대문자야?
함수인가? 상수? 클래스.. 파악해보자.
와..
네이밍 규칙
하나 혹은 두개로 통일해서 사용합시다
네이밍을 잘 지켜야 할까?
컨벤션을 지키는 이유
lint를 써서 코드 규격을 하는 이유
결국, 가독성과 소통
쉽게 읽고, 다른 개발자와 소통하기 위함
Statement, if
저는 IF문 혐호합니다.
중첩 if 자제 합시다.
• 중첩 if 를 남용한 순간,
• If 키워드 하나 당 적어도 2배 이상 복잡도가 증가
코드가 상태에 의존되게 하지마
• If 블록을 나눌 수 있는지
• 저는 상태 분기점(if)는 두 개만 중첩되도 과하다고 생각합니다.
If문 statement
If 예제 (실전)
결제수단에 따라 금액 조건 처리하기.
BAD CASE
실제 코드 (살짝 수정)
GOOD CASE GOOD CASE
결제 메인 로직
인터페이스 설계가 명확하면 이후 내부 로직도 분명합니다.
GOOD CASE
조건문 내 상태는 간결하게
Enum 값은 명시 및 관리 해줍시다.
BAD CASE GOOD CASE
Array, loop
for
• For loop 쓰지마…
• Index 관리
For(let I = 0; I < n; i++) {
console.log(list[i])
}
list 내 몇 번째 값을 어쩌구…
List.forEach(item => {
console.log(item)
})
왜 쓰면 안될까?
• 미관상의 이유?
• 관리 포인트가 늘어난다. 어느 배열의 몇 번 째 값
For 대신 다른 함수는 속도 이슈가 있다??
속도가 느리다는 핑계 =>
그 정도의 많은 데이터를 어플리케이션에서 루프를 돌면서 다루는
거 자체가 문제임
JS는 예외. 속도가 크게 차이가 안 남.
개발자들이 하도 그렇게 쓰니까
V8엔진에서 자체 최적화를 해버림…
JS 개발자면 mdn에 자주 들어갑시다
https://developer.mozilla.org/ko/docs/Web/JavaScript
함수
Return은 일관되게 하자 : 타입
분기에 따라 다른 타입을 반환하지 말자.
BAD CASE
Return은 일관되게 하자 : 필드
분기에 따라 다른 필드를 주지 말자
=> 명확하게 표현 BAD CASE GOOD CASE
Return은 일관되게 하자 : 동기/비동기
• 상태에 따라 동기식? 비동기? 통일해주자.
BAD CASE GOOD CASE
콜백 대신 async, await
콜백 지옥… 숨막힙니다
[토론]중복된 코드 제거가 무조건
정답일까?
https://github.com/qkraudghgh/clean-code-javascript-ko#중복
된-코드를-작성하지-마세요
리팩토링 실습 코드
예제 데이터 셋
ASIS: 고민해봅시다
뭐하는 기능일까?
TOBE:
1. 할인률 계산
2. 한정판 게임 금액 계산
3. 세금 계산
클래스 정의
메소드 정의
메소드 정의
끝으로 한마디
제가 생각하는 리펙토링은
어떻게 풀어나갈지 생각하고 시행착오를 거쳐 나가는 과정
중요) 리팩토링 성공척도 == 테스트코드
JS는 유연합니다.
https://velog.io/@teo/functional-programming
객체지향, 함수형 등등으로 다양한 방식으로 표현이 가능
상황에 따라 장점만 취합시다.
개발의 뱡향성? 가치관? 아만보, 쓰쓰쓰
Reference
<사이트>
[clean-code-javascript] https://github.com/qkraudghgh/clean-code-javascript-ko
[언제, 어디에 리팩토링을 해야할까 (When, Where)] https://taes-k.github.io/2-where-when-refactoring.html
[실전주의 프론트엔드] https://peter-cho.gitbook.io/book/
<도서>
심플소프트웨어
개발자의 글쓰기
속깊은 Javascript
Effective java
Effective C++
Effective python
<코드 출처>
본인
감사합니다

리팩토링