[리팩토링] 악취 18 : 중재자

 

✍️ 악취 18 : 중재자

메서드 호출을 위해 중간에 거쳐가는 존재를 말 그대로 중재자라고 한다. 구조에 따라서 중재자가 필요할 수도 불필요할 수도 있다. 다만 과도한 위임이 발생해서 메서드 호출마다 항상 중재자를 거쳐가야 한다면 중재자를 제거하는 방향으로 리팩토링할 수 있다.

 

여기 중재자 악취를 해결하기 위한 리팩토링 기법이 있다.

1. "중재자 제거하기중재자를 거치지 않고 클라이언트가 직접 객체를 사용하기

 

🍊 중재자 제거하기

'중재자 제거하기'는 캡슐화를 제거하고 메시지 체인을 사용한단 의미에서 '위임 숨기기'와 반대된다. 오히려 위임을 드러내는 리팩토링이다.

* 개인적으로 메시지 체인보단 캡슐화로 필요한 정보만 제공하는것이 더 객체지향스럽다고 생각한다. 실제로도 대부분의 업무에선 캡슐화를 하는 쪽이 절대 다수였다. 다만 예외적인 상황은 존재한다. 예를들어, 내부 객체에 필드가 추가되면 중재자 메서드도 함께 추가돼야한다. 즉, 필드가 추가될때마다 중재자 메서드도 선형적으로 증가하는 케이스라면 위임을 제거하기도 했다.
* 결론!
 캡슐화의 정도에 따라 "중재자 제거하기"와 "위임 숨기기"를 적절히 조절하는 것을 고려하자.

 

클라이언트가 Person의 Information에 직접 접근하는 것을 감추고자 위임 숨기기를 적용한 케이스.

@AllArgsConstructor
public class Person {

    @Getter
    private int personId;
    private Information info;

    // 중재자
    public String getName() {
        return info.getName();
    }
    
    // 중재자
    public String getAddress() {
        return info.getAddress();
    }
}

@AllArgsConstructor
@Getter
public class Information {

    private String name;
    private String address;
}

class PersonTest {
    
    @Test
    void test() {
        Person person = new Person(1, new Information("kang", "seoul"));
        String address = person.getAddress();

        assertEquals("seoul", address);
    }
}

 

반대로 위임이 과도하고 클라이언트가 메시지 체인 구조를 알아도 무방하다고 판단되면 중재자를 제거하고 메시지 체인을 사용하도록 변경할 수 있다.

@AllArgsConstructor
@Getter
public class Person {

    private int personId;
    private Information info;
}

class PersonTest {

    @Test
    void test() {
        Person person = new Person(1, new Information("kang", "seoul"));
        String address = person.getInfo().getAddress();

        assertEquals("seoul", address);
    }
}