스터디/리팩토링 2판 7

[리팩토링 2판] 11장. API 리팩토링 (11월 24일, 12월 8일)

질의 함수와 변경 함수 분리하기 외부에서 관찰할 수 있는 겉보기 부수효과(사이드 이펙트)가 전혀 없이 값을 반환해주는 함수를 추구해야 한다. 함수가 사이드 이팩트가 있다는 것은 한 가지 일을 하기로 했는데 여러 가지 일을 하는 것이다. // before // 아래의 함수는 이름처럼 2가지 일을한다. (부수효과는 아니다) function totalOutstandingAndSendBill() { const result = customer.invoices.reduce( (total, each) => each.amount + total, 0); sendBill(); return result; } // after function totalOutstanding() { return customer.invoices.r..

[리팩토링 2판] 10장. 조건부 로직 간소화 (11월 16일)

조건부 로직은 프로그램을 복잡하게 만드는 주요 원흉이기도 하다. 조건문 분해하기 조건을 검사하고 그 결과에 따른 동작을 표현하는 코드는 무슨 일이 일어나는지는 이야기해주지만 왜 일어나는지는 말하지 않는다. 거대한 코드 블록을 부위별로 분해하고 의도를 살린 이름의 함수 호출로 바꾸자. 거대한 코드 블록이 주어지면 코드를 부위별로 분해한 다음 의도를 살린 이름의 함수 호출로 바꾸자. // before if (!date.isBefore(plan.summerStart) && !date.isAfter(plan.summerEnd)) { charge = quantity * plan.summerRate; } else { charge = quantity * plan.regularRate + plan.regularServ..

[리팩토링 2판] 9장. 데이터 조직화 (11월 9일)

이번 장은 데이터 구조에 집중한 리팩토링이다. 변수 쪼개기 역할이 둘 이상인 변수는 쪼개야 한다. 역할 하나당 변수 하나다. function distanceTravelled(scenario, time) { let result; let acc = scenario.primaryForce / scenario.mass; // 가속도(a) = 힘(F) / 질량(m) let primaryTime = Math.main(time, scenario.delay); result = 0.5 * acc * primaryTime * primaryTime; // 전파된 거리 let secondaryTime = time - scenario.delay; if (secondaryTime > 0) { // 두 번째 힘을 반영해 다시 계산..

[리팩토링 2판] 7장. 캡슐화, 8장. 기능 이동 (11월 2일)

기본형을 객체로 바꾸기 처음에는 단순한 문자열로 시작해서 나중에는 포맷팅, 특별한 동작이 추가되는 등 중복 코드가 늘어나고 사용할 때마다 드는 노력도 늘어난다. 출력 이상의 기능이 필요해지는 순간 클래스를 정의하면 좋다. 클래스로 집중시켜 놓으면 관련된 로직을 한 곳에서 관리할 수 있으면 중복된 코드를 처리할 수 있다. // before class Order { constructor(data){ this.priority = data.priority; } } highPriorityCount = orders.filter (o => "high" === o.priority || "rush" === o.priority).length; // after class Order { constructor(data){ th..

[리팩토링 2판] 6장. 기본적인 리팩토링 (10월 19일)

함수 추출하기 코드 조각을 찾아 무슨 일을 하는지 파악한 다음, 독립된 함수로 추출하고 목적에 맞는 이름을 붙인다. 코드를 언제 독립된 함수로 묶어야 할지에 관한 의견은 많다. 길이, 반복되는 횟수 등등 많지만 ‘목적과 구현을 분리’하는 방식이 가장 합리적으로 보인다. 코드를 보고 무슨 일을 하는지 파악하는 데 한참이 걸리면 함수로 추출한 뒤 걸맞은 이름을 짓는다. 함수를 새로 만들고 목적을 잘 드러내는 이름을 붙인다(’어떻게’가 아닌 ‘무엇을’ 하는지) 추출할 코드를 원본 함수에서 복사하여 새 함수에 붙여넣는다. 추출한 코드 중 원본 함수의 지역 변수를 참조하거나 추출한 함수의 유효 범위를 벗어나는 변수는 없는지 검사한다. 있다면 매개변수로 전달한다. 변수를 다 처리했다면 컴파일한다. 원본 함수에서 추..

[리팩토링 2판] 3장. 코드에서 나는 악취 (10월 12일)

리팩토링을 언제 멈춰야 하는지를 판단하는 정확한 기준은 제시하지 않을 것이다. 왜냐하면 숙련된 사람의 직관만큼 정확한 기준은 없기 때문이다. 아래의 소제목들은 피해야 하는 것들이다. 기이한 이름 이름만 보고도 무슨 일을 하고 어떻게 사용해야 하는지 명확히 할 수 있도록 짓는다. 이름만 보고도 동작을 유추할 수 있다면 코드 파악하는 시간을 많이 줄일 수 있다. 그리고 코드를 읽는 사람이 코드에 더 신뢰성을 가질 수도 있다. 중복 코드 똑같은 코드 구조가 여러 곳에서 반복된다면 하나로 통합하자. 중복 코드는 그 순간 편하겠지만 수정으로 들어가는 순간 지옥길 시작이다.. 긴 함수 긴 함수보다 짧은 함수가 코드를 이해하는데 더욱 도움이 된다. 짧은 함수로 구성된 코드를 이해하기 쉽게 만드는 가장 확실한 방법은 ..

[리팩토링 2판] 2장. 리팩토링 원칙 (10월 12일)

리팩토링 정의 리팩토링 → 겉보기 동작은 유지한 채, 이해하기 쉽게 내부 구조를 변경하는 기법 리팩토링 과정에서 발견된 버그는 리팩토링 후에도 남아 있어야 한다. 리팩토링은 코드를 이해하고 수정하기 쉽게 만드는 것이다. 리팩토링을 진행하며 버그를 고치지 말라고 하는데... 눈앞에 버그를 놔두고 지나가야 하는 건가 라는 의문이 든다. 리팩토링 하는 이유 코드만 봐서는 설계를 파악하기 어렵다. 코드량이 줄면 수정하는데 드는 노력은 크게 달라진다. 모든 코드가 언제나 고유한 일을 수행함을 보장한다. 내 의도를 더 명확하게 전달하기 위해 다른 사람을 배려하기 위해서가 아니라 바로 나 자신을 위해 버그를 찾기 쉽다. 기억할 필요가 있는 것들은 최대한 코드에 담아내자 (외부에 담으려 X) 일단 리팩토링을 하는 이유..