리팩토링 - 냄새 17. 메시지 체인

김상운(개발둥이)·2022년 4월 8일
0

리팩토링

목록 보기
14/17
post-thumbnail

들어가기

해당 포스팅은 인프런 백기선님의 '리팩토링'을 학습 후 정리한 내용입니다.



냄새 17. 메시지 체인

Message Chains

  • 레퍼런스를 따라 계속해서 메소드 호출이 이어지는 코드.
    • 예) this.member.getCredit().getLevel().getDescription()
  • 해당 코드의 클라이언트가 코드 체인을 모두 이해해야 한다.
  • 체인 중 일부가 변경된다면 클라이언트의 코드도 변경해야 한다.
  • 관련 리팩토링
    • 위임 숨기기 (Hide Delegate)”를 사용해 메시지 체인을 캡슐화를 할 수 있다.
    • “함수 추출하기 (Extract Function)”로 메시지 체인 일부를 함수로 추출한 뒤, “함수 옮기기
      (Move Function)”으로 해당 함수를 적절한 이동할 수 있다.

위임 숨기기

Hide Delegate

  • 캡슐화 (Encapsulation)란 어떤 모듈이 시스템의 다른 모듈을 최소한으로 알아야 한다는 것이다. 그래야 어떤 모듈을 변경할 때, 최소한의 모듈만 그 변경에 영향을 받을 것이고, 그래야 무언가를 변경하기 쉽다.
  • 처음 객체 지향에서 캡슐화를 배울 때 필드를 메소드로 숨기는 것이라 배우지만, 메소드 호출도 숨길 수 있다.
    • person.department().manager(); -> person.getManager()
    • 이전의 코드는 Department를 통해 Manager에 접근할 수 있다는 정보를 알아야 하지만, getManager()를 통해 위임을 숨긴다면 클라이언트는 person의 getManager()만 알아도 된다. 나중에 getManager() 내부 구현이 바뀌더라도 getManager()를 사용한 코드는 그대로 유지할 수 있다.

예제 코드

Department

public class Department {

    private String chargeCode;

    private Person manager;

    public Department(String chargeCode, Person manager) {
        this.chargeCode = chargeCode;
        this.manager = manager;
    }

    public String getChargeCode() {
        return chargeCode;
    }

    public Person getManager() {
        return manager;
    }
}

Person

public class Person {

    private String name;

    private Department department;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }
}

테스트 코드

class PersonTest {

    @Test
    void manager() {
        Person keesun = new Person("keesun");
        Person nick = new Person("nick");
        keesun.setDepartment(new Department("m365deploy", nick));

        Person manager = getManager(keesun);
        assertEquals(nick, manager);
    }

    private Person getManager(Person keesun) {
        return keesun.getDepartment().getManager();
    }

}

냄새

테스트 코드에서 manager 를 알기 위해서 계속된 참조를 통해서 알아내고 있다.

해결

위임 함수를 사용하여 캡슐화한다.

리팩토링 후

Person

public class Person {

    private String name;

    private Department department;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    Person getManager() {
        return getDepartment().getManager();
    }
}

설명

getMaganer() 위임 함수를 추가하여 캡슐화하여 사용한다.

profile
공부한 것을 잊지 않기 위해, 고민했던 흔적을 남겨 성장하기 위해 글을 씁니다.

0개의 댓글