개발 이야기 안하는 개발자

12장 상속 다루기 본문

Book/리팩터링 2판

12장 상속 다루기

07e 2023. 6. 15. 01:18
반응형

리팩터링 12번째 장 - 상속 다루기

 

상속은 굉장히 유용하면서 동시에 오용하기 쉽다

보통 상속을 사용하는 경우는 여러개의 비슷한 기능을 하는 클래스들을 묶는 것에 사용하는데

그렇기 때문에 해당 리팩터링은 하나이상의 클래스들을 정리하는데에 사용된다.


1. 메서드 올리기

왼쪽은 원래 기본 코드

코드를 보면 같은 부모이고 AFunc() 같은 내용의 메소드를 쓰고있다.

이를 오른쪽 처럼 부모에 메서드를 올리면 된다.

 

<진행>

1) 똑같은 기능의 메서드인가?

 -> 실질적 일이 같은데 코드가 다르면 코드가 똑같아질때 까지 리팩터링 해야한다.

2) 참조하는 다른 필드들은 부모클래스로 올릴수 있는지 확인해본다.

3) 메서드이름이 다르면 이름부터 바꾸고 부모클래스로 올린다.

 


2. 필드 올리기

메서드 올리는 방식과 비슷하다.

 

<진행>

1) 사용하는 곳 모두에게 같은 방식인가 확인해 본다.

2) 이름을 같게 바꾸고, 부모에게 새로운 필드를 생성한다.


3. 생성자 본문 올리기

자식 클래스들이 생성자를 사용한다면 부모 클래스에 생성자를 새로 만들고 정리를 해두는 편이 좋다.

 

<진행>

1) 부모클래스에 생성자 제작.

2) 문장 슬라이드해서 겹치는 메서드는 모두 부모에게 올린다.

3) 자식 클래스에서 올린 것들 모두 삭제


4. 메서드 내리기

만약 부모 메서드가 특정 클래스만 사용하는 메서드라면

해당 메서드는 해당 클래스로 내려가야 한다.

 

<진행>

1) 해당 메서드를 모든 자식 클래스에 복사해서 넣는다.

2) 부모 클래스는 이를 삭제한다.

3) 테스트하면서 자식 클래스중에 해당 메서드를 사용하지 않는 클래스에선 삭제한다.

 


5. 필드 내리기

메서드 내리기와 같은 원리이다.

 

<진행>

1) 해당 필드를 모든 자식에게 적용해본다.

2) 부모에서 이를 삭제한다.

3) 테스트하면서 하나씩 제거한다.


6. 타입 코드를 서브클래스로 바꾸기

스크립트를 타입에 맞춰 한 클래스에 몰아넣어서 제작한 경우가 종종있다.

이는 역할별로 나누어 주는것이 보기더 좋다.

 

외부에서 switch문을 사용했기 때문에 정해진 종류만 뽑아서 사용하도록 하였고

클래스는 자식 클래스를 제작해서 각 역할에 맞는 기능들을 넣도록 수정한다.

 

<진행>

1) 타입코드 값 하나를 선택해서 서브 클래스를 제작한다.

2) 매개변수로 받은 Type와 방금 만든 서브클래스를 매핑하는 선택 로직(switch문)을 제작한다.

3) 테스트하여 문제가 없는지 확인한다.

4) 모든 타입을 위와 같은 방식으로 반복한다.

 


7. 자식 클래스 제거하기

왼쪽은 실행 코드이고, 오른쪽은 리팩터링이 필요한 클래스이다.

우선 왼쪽코드는 어떠한 데이터 배열이 있고, 필요에 의해 이를 클래스로 재정리를 하게 되었다는 내용을 담고있다.

오른쪽 코드를 보면 많은 내용을 담고 있지 않기 때문에 오히려 코드가 길어지고 보기 불편해진다.

 

 

이러한 경우는 자식 클래스가 코드가 바뀌고 변경됨에 따라 그 의미가 없어지는 경우가 있다.

이렇게 자식 클래스가 가치가 없거나, 거의 사용되지 않을 정도로 의미가 없어지면 위처럼 줄여서 쓰는게 좋다.

 

<진행>

1) 자식 클래스의 생성자를 팩터리 함수로 바꾼다.

2) 자식 클래스의 타입을 검사하는 코드가 있다면 부모로 올린다.

3) 자식 클래스의 타입을 나타내는 필드를 부모 클래스로 올린다.

4) 자식 클래스를 지운다.


8. 부모 클래스 추출하기

다른 클래스이지만 같은 기능 또는 비슷한 기능을 하게 될 경우 하나의 부모로 묶어서 클래스를 사용하는 것이 더 가독성이 좋아진다.

 

<진행>

1) 부모 클래스 만들어서 상속하기

2) 생성자 / 메서드 필드 올리기

3) 테스트 및 더 필요한거 있나 확인하기

4) 부모클래스에 인터페이스를 사용할지 고민해 볼것.

 


9. 계층 합치기

어떤 클래스와 그 부모가 너무 비슷해져서 더는 독립적으로 존재할 필요가 없어질때 사라져야 한다.

이때가 합쳐야 할 때이다.

 


10. 자식 클래스를 위임으로 바꾸기

 

자식코드가 부모코드에게 많이 의존을 하면 부모 클래스가 수정을 하면 자식 클래스는 이에 많은 영향을 받을 것이다. 그렇기 때문에 코드를 수정할땐 부모 클래스와 자식 클래스에 대한 관계에 대해 높은 이해를 요구하게 된다.

이때 부모와 자식이 다른 모듈에 속하게 되면 문제는 더 커진다.

위임은 이 현상을 해결해 줄 수 있다.

해당 방법은 계층 구조를 설계하는 방법에 좀더 가깝다.

 

<진행>

1) 생성자를 호출하는 곳이 많다면 생성자를 팩터리 함수로 바꾼다.

2) 위임으로 활용할 빈 클래스를 제작한다.

3) 위임을 저장할 필드를 부모 클래스에 추가한다.

4) 자식 클래스 생성코드를 수정하여 위임 인스턴스를 생성하고 위임 필드에 대입해 초기화한다.

5) 자식 클래스 몇몇은 필요하다면 위임클래스로 이동한다.

6) 자식 클래스들의 생성자를 호출하는 코드를 찾아서 부모 클래스의 생성자를 사용하도록 수정한다.

 


11. 부모 클래스를 위임으로 바꾸기

스크립트를 짜다보면 서브클래스가 더 많은 기능을 하고 있고, 부모 클래스는 역할이 거의 없는 경우가 생긴다.

이는 짜임새가 좋지않아 다른 개발자가 보면 혼란을 야기할 수 있게 되는 원인이 된다.

 

따라서 자식클래스가 부모클래스를 가져다가 사용 하는 방식으로 사용하면 된다.

 

<진행>

1) 부모슈퍼클래스 객체를 참조하는 필드를 서브클래스에 만든다.

2) 부모 클래스의 동작에 대응하는 전달 함수를 자식에게 만든다.

3) 위를 정리해가며 테스트하고, 불필요한 코드를 삭제한다.

4) 모두 끝났으면 자식의 상속 부분을 삭제한다.

반응형

'Book > 리팩터링 2판' 카테고리의 다른 글

4장 테스트 구축하기  (0) 2023.06.09
3장 코드에서 나는 악취  (2) 2023.06.09
2장 리팩터링 원칙  (0) 2023.05.27
1장 : 리팩터링  (0) 2023.05.27