본문 바로가기

독서에서 한걸음52

Refused Bequest 상속 포기라는 뜻으로 서브클래스가 슈퍼클래스에서 제공하는 메서드나 데이터를 잘 활용하지 않는다는 것은 해당 상속 구조에 문제가 있다는 것이다. 기존의 서브클래스 또는 새로운 서브클래스를 만들고 슈퍼클래스에서 메서드와 필드를 내려주어 슈퍼클래스에는 공동으로 사용하는 기능만 남길 수 있다. 서브클래스가 슈퍼클래스의 기능을 재사용하고 싶지만 인터페이스를 따르고 싶지 않은 경우에는 슈퍼클래스 또는 서브클래스를 위임으로 교체하여 사용한다. public class Employee { protected Quota quota; protected Quota getQuota() { return new Quota(); } } public class Salesman extends Employee { } public class.. 2022. 12. 28.
Alternative Classes with Different Interfaces 서로 다른 인터페이스의 대안 클래스들이라는 뜻으로 비슷한 일을 여러 곳에서 서로 다른 규약을 사용해 지원하고 있는 코드의 냄새를 말한다. 대안 클래스로 사용하려면 동일한 인터페이스를 구현하고 있어야 한다. 보통 함수 선언 변경하기와 함수 옮기기를 사용하여 서로 동일한 인터페이스를 구현하게끔 코드를 수정할 수 있다. 두 클래스에서 일부 코드가 중복되는 경우에는 슈퍼클래스로 추출하여 중복된 코드를 슈퍼클래스로 옮기고 두 클래스를 새로운 슈퍼클래스의 서브클래스로 만들 수 있다. 산발적으로 비슷한 기능을 조금씩 다르게 만드는 코드가 보인다면 다음 리팩토링을 진행해 보자. public class OrderAlerts { private AlertService alertService; public void alert.. 2022. 12. 27.
Large Class 어떤 클래스가 너무 많은 일을 하다 보면 필드도 많아지고 중복 코드도 보이기 시작한다. 클라이언트가 해당 클래스가 제공하는 기능 중에 일부만 사용한다면 각각의 세부기능을 별도의 클래스로 분리할 수 있다. 필드들이 모이다보면 결국 필드를 사용하는 기능들이 점점 모아지고 나중에 떼어내기가 매우 힘들어진다. 이 경우 관련있는 필드를 클래스 추출하기를 통해 한 곳으로 모을 수 있다. 만약 상속 구조를 만들 수 있다면 슈퍼 클래스 추출하기 또는 타입 코드를 서브클래스로 교체하기를 적용할 수 있다. 이 중 슈퍼클래스를 추출하기를 해보자. Extract Superclass 두 개의 클래스에서 비슷한 것들이 보인다면 상속을 적용하고 슈퍼클래스로 필드 올리기와 메서드 올리기를 사용한다. 대안으로는 클래스 추출하기를 적용.. 2022. 12. 26.
Insider Trading 내부자 거래라는 뜻으로 어떤 모듈이 다른 모듈의 내부 정보를 지나치게 많이 알고 있는 코드냄새이며, 그로 인해 지나치게 강한 결합도가 생길 수 있다. 보통 적절한 모듈로 함수를 옮기거나, 필드를 옮겨 결합도를 낮출 수 있다. 어떤 모듈이 자주 사용하는 공통적인 기능은 새로운 모듈을 만들어 잘 관리하거나, 위임을 숨기는 함수를 만들어 특정 모듈의 중재자처럼 사용할 수도 있다. 상속으로 인한 결합도를 줄일 때는 슈퍼클래스 또는 서브클래스를 위임으로 교체하여 사용할 수 있다. public class Ticket { private LocalDate purchasedDate; private boolean prime; public Ticket(LocalDate purchasedDate, boolean prime) .. 2022. 12. 26.
Middle Man 메시지 체인의 반대라고 생각하는 중재자라는 뜻을 가진다. 캡슐화를 통해 내부의 구체적인 정보를 최대한 감출 수 있다. 그러나 어떤 클래스의 메서드가 대부분 다른 클래스로 메서드 호출을 위임하고 있다면 중재자를 제거하고 클라이언트가 해당 클래스를 직접 사용하도록 코드를 개선할 수 있다. 도메인 객체를 사용할 때 해당 냄새가 난다면 클라이언트의 참조를 의심해 볼만하다. 관련 리팩토링으로는 다음과 같다. Remove Middle Man으로 클라이언트가 필요한 클래스를 직접 사용하도록 개선할 수 있다. Inline Function을 통해 메서드 호출한 쪽으로 코드를 보내 중재자를 없앨 수도 있다. Replace Superclass with Delegate, Replace Subcalss With Delegate.. 2022. 12. 24.
Message Chains 메시지 체인. 우리는 this.member.getCredit(). getLevel(). getDescription()과 같은 체인 형태를 본 적이 있고 사용한 적이 있다. 이는 레퍼런스를 따라 계속해서 메소드 호출이 이어지는 코드이다. 나는 최근 이러한 코드를 한번 호출하도록 고쳤다. 그 이유는 위와 같은 메시지 체인이 반복되었고 이를 통해 이 책임은 해당 객체에 있다는 것을 깨닫고 즉시 메서드를 만들어서 책임을 넘겨주었다. 혹은 해당 객체를 여기서 사용하는 것이 맞는지 이 참조가 해당 클래스에 위치하는지 검토하기도 했다. 만약 메시지 체인을 사용한다면 다른 개발자들은 해당 코드의 클라이언트가 코드 체인을 모두 이해해야 한다. 만약 체인 중 일부가 변경된다면 클라이언트의 코드도 변경해야 한다. 나는 함수.. 2022. 12. 24.
Temporary Field 클래스에 있는 어떤 필드가 특정한 경우에만 값을 갖는 경우 어떤 객체의 필드가 특정한 경우에만 값을 가진다는 것을 이해하는 것은 일반적으로 예상하지 못하기 때문에 이해하기 어렵다. 보통 클래스 추출하기를 통해 해당 변수를 옮길 수 있다, 혹은 함수 옮기기를 사용해서 해당 변수를 사용하는 함수를 특정 클래스로 옮길 수 있다. Introduce Special Case라는 특이 케이스 추가하기를 적용해 특정한 경우 해당하는 클래스를 만들어 해당 조건을 제거할 수도 있다. Introduce Special Case 특이 케이스 추가하기. 어떤 필드에 특정한 경우에만 값이 설정되는 경우 해당 특정한 값에 따라 동일하게 동작하는 코드가 반복적으로 나타난다면, 해당 필드를 감싸는 특별 케이스를 만들어 해당 조건을 표현.. 2022. 12. 24.
Speculative Generality 추측성 일반화라는 이름으로 나중에 이러저러한 기능이 생길 것을 예상하여, 기능을 만들었지만 결국 쓰이지 않는 코드가 발생한 경우이다. 이는 다양하게 적용될 예시가 있다. 1. 추상 클래스를 만들엇지만 크게 유효하지 않다면 Collapse Hierarchy으로 계층을 합친다. 2. 불필요한 위임은 함수 인라인 혹은 클래스 인라인으로 처리한다. 3. 사용하지 않는 매개변수를 가진 함수는 Change Function Declaration을 적용한다. 4. 오로지 테스트 코드에서만 사용하고 있는 코드는 Remove Dead code를 적용한다. 나는 4번에 관심이 있다. Remove Dead Code 사용하지 않는 코드가 애플리케이션 성능이나 기능에 영향을 끼치지는 않는다. 하지만 해당 소프트웨어가 어떻게 동작.. 2022. 12. 24.
Lazy Element 여러 프로그래밍적인 요소를 만드는 이유. 1. 나중에 발생할 변화를 대비해서 생성한다. 2. 해당 함수 또는 클래스를 재사용하려고 한다. 3. 의미 있는 이름을 가진 변수를 사용하려고 한다. 가끔 그렇게 예상하고 만들어 놓은 요소들이 기대에 부응하지 못하는 경우 해당 요소를 제거해야 한다. 보통 함수를 인라인 화하여 처리하거나, 불필요한 클래스를 인라인 시킨다. 불필요한 상속 구조는 계층을 합치는 (Collapse Hierarchy)를 사용할 수 있다. Collapse Hierarchy 보통 상속 구조를 리팩토링하려고 메서드를 상위 클래스로 올리거나 내리다 보면 하위클래스와 상위 클래스 코드에 차이가 없는 경우가 발생할 수 있다. 그러한 경우 그 둘을 합칠 수있는데, 어떤 것을 없애야 할까? 보통 둘 중.. 2022. 12. 24.
Repeated Switches 반복되는 switch문에 대한 리팩토링이다. 예전에는 switch문이 한 번만 등장해도 다형성 적용을 권장했지만, 최근에는 다형성이 널리 사용되고, 여러 프로그래밍 언어에서 세련된 형태의 switch문을 지원하고 있다. 따라서 오늘날은 반복해서 등장하는 동일한 swich문을 냄새로 여긴다. 반복해서 동일한 switch문이 존재할 경우, 새로운 조건을 추가하거나 기존의 조건을 변경할 때 모든 switch문을 찾아서 코드를 고쳐야 한다., 동일한 switch문에 적용된다. 이는 전에 배웠던 다형성을 적용하여 리팩터링 할 수 있다. 저자도 과거에 비해 현재 프로그래밍 언어의 switch문의 가독성을 향상하는 방법이 많기 때문에 한 번의 switch문에 대해 리팩토링을 권장하지는 않는다. 그럼 스위치문이 어떻게.. 2022. 12. 22.