소프트웨어는 변경에 유연하게 대처할 수 있어야 된다.
응집력은 높고 결합도는 낮게
어떠 한 모듈이(함수 또는 클래스가) 여러가지 이유로 다양하게 변경되어야 하는 상황.
- 단계 쪼개기 => 서로 다른 문맥 코드 분리
- 함수 옮기기 => 적절한 모듈로 옮기기
- 함수 추출하기 => 여러가지 일이 하나의 함수에 모여 있으면
- 클래스 추출하기 => 모듈이 클래스 단위 이면
서로 다른 일을 하는 코드를 각기 다른 모듈로 분리
=> 그래야 오류가나도 서로 영향을 주지않고 해당 부분만 수정 하면된다.
여러 일을 하는 함수의 처리 과정을 각기 다른 단계로 구분
예) 컴파일러: 텍스트 읽어오기 -> 실행 가능한 형태로 변경
중간 데이터를 만들어 단계를 구분하고 매개변수를 줄이는데 활용!
다른 역활을 하는 한쪽을 메서드 추출로 분리해준다.
중간데이터(Record) 를 활용해 단계를 구분하고 중간데이터를 활용
Record에다가 필요한 매개변수들을 넣어서 통쨰로 보낸다. -> 메서드 실행하는쪽의 매개변수를 줄일수 있다.
함수가 포함된 문맥(클래스) 에서 외부에서 더 참조를 많이 한다면 함수 옮기기를 고민해보자
함수를 어디다 둬야할지모르면 ( 애매하면 = 여기저기쓰이면). 그냥 그대로 둬도 좋다
함수의 위치 고려하기
위 overdraftCharge는 사실상 참조반 포함된 문맥 반 이지만 한번 참조한 클래스로 함수를 옮겨보자
참조 클래스 AccountType를 더 많이 쓴다고 가정해보자
Refactor -move instance method
Account 안에 데이터중 여러데이터를 사용하면 Account 통쨰로 받는것이 좋지만 우리는 필드값 하나만 필요함으로 그값 하나만 파라미터로 받는다
함수를 옮겼을때 Account 객체 통쨰로 넘겨주면 Account -> AccountType 참조연관/. 그반대로도 성립하기떄문에 좋지않다. 그래서 필요한 필드값만 매개변수로 넘겨준다
이렇게 하면 응집력은 높아지면서 결합도는 낮아지는 좋은 코드가 된다.
1.데이터나 메소드 중 일부가 매우 밀접한 관계가 있는 경우
2.일부 데이터가 대부분 같이 바뀌는 경우
클래스가 한눈에봐도 들어가있는게 많다.(= 책임이 많다)
서로서로 조금더 밀접한 관계가 있는것들을 찾아준다. 위에서는 officeAreacode 와 officeNumber
호출 하는쪽도 이름을 그에 걸맞게 수정해준다.
getTelephoneNumber은 메서드위치기 TelephoneNumber 클래스가 더 적절함으로 옮겨준다.
어떠 한 변경 사항이 생겼을때 여러 곳을 수정 해야 하는 상황(산탄총을 맞으면 여러곳이 구멍 슝슝)
"뒤엉킨 변경" 과 흡사하지만 반대의 상황/ 산탄총 수술은 반대로 합친다.
- 함수 옮기기/ 필드 옮기기 => 필요한 변경 내역을 하나의 클래스로 모으기
- 여러 함수를 클래스로 묶기 => 비슷한 데이터를 사용하는 여러 함수 묶기
- 단계 쪼개기 => 공통으로 사용되는 함수의 결과물 하나로 묶기
클래스 합치기
리팩토링을 하는 도중에 클래스의 책임을 옮기다보면 클래스의 존재 이유가 빈약 해지는 경우가 발생
필드옮기기 -> 생성자 -> 메서드 수정
-두개의 클래스를 여러 클래스로 나누는 리팩토링 경우-
1. 우선 "클래스 인라인" 을 활용하여 두클래스를 한곳으로 모은다
2. 그다음 "클래스 추출"하기로 새롭게 분리
이 두 클래스에서 areacode , number 은 항상 같이 다니기 떄문에 데이터 뭉치라고 볼수 있다.
데이터 뭉치들을 한번에 묶는 클래스를 따로 만들어준다. ( getter/setter/constructor)
Employee 쪽에 그 클래스를 적용시킨다. -> toString() 으로 우리가 필요한 메서드를 만들어준다.
반대쪽도 똑같이 정리해준다.
telephoneNumber 의 필드값들의 이름이 그전에는 그이름들이 맞았지만 employee도 참조를 하니 좀더 일반적인 이름으로 수정 해준다