독서이야기/엘레강트 오브젝트 - 새로운 관점에서 바라본 객체지향

[엘레강트 오브젝트] 3.6 부 ctor 밖에서는 new를 사용하지 마세요

사랑꾼이야 2023. 3. 22. 23:41
반응형

이 내용은 엘레강트 오브젝트 를 읽으면서 정리한 내용을 포함하고 있습니다.

  • 부 ctor와 의존성
  • 정리

부 ctor와 의존성

class Cash {
    private final int dollars;

    public int euro() {
        return new Exchange().rate("USD", "EUR") * this.dollars;
    }
}
  • 문제을 일으킨 범인의 이름은 하드코딩된 의존성인 new 연산자이다.
    • new Exchange()
  • Cash 클래스는 Exchange 클래스에 직접 연결되어 있기 때문에, 의존성을 끊기 위해서는 Cash 클래스의 내부 코드를 변경할 수 밖에 없다.

메서드 내부에서 new 연산자를 사용할 수 없도록 금지했다고 가정해본다면, 이제 객체가 새로운 객체를 직접 생성할 수 없기 때문에, 새로운 객체를 ctor의 인자로 전달 받아 private 프로퍼티 안에 캡슐화할 수 밖에 없다.

class Cash {
    private final int dollars;
    private final Exchange exchange;

    Cash(int value, Exchange exch) {
        this.dollars = value;
        this.exchange = exch;
    }

    public int euro() {
        return this.exchange.rate("USD", "EUR") * this.dollars();
    }
}
  • 수정한 코드에서는 두번째 인자에 Exchange 인스턴스를 전달한다.
  • Cash 클래스는 더이상 Exchange 인스턴스를 직접 생성할 수 없다.

객체가 필요한 의존성을 직접 생성하는 대신, 우리가 ctor를 통해 의존성을 주입한다.

class Cash {
    private final int dollars;
    private final Exchange exchange;

    Cash() {
        this(0);
    }

    Cash(int value) {
        this(value, new NYSE());
    }

    Cash(int value, Exchange exch) {
        this.dollars = value;
        this.exchange = exch;
    }

    public int euro() {
        return this.exchange.rate("USD", "EUR") * this.dollars();
    }
}
  • 주 ctor를 사용할 경우에는 객체와 협력하는 모든 의존성을 우리 스스로 완전히 제어할 수 있다.
  • 부 ctor를 제외한 어떤 곳에서도 new를 사용하지 말아야 한다.

정리

  • 부 ctor에서만 new를 사용해야 한다는 간단한 규칙을 불변 객체와 조합하면, 코드는 깔끔해지고 언제라도 의존성을 주입할 수 있게 될 것이다.
반응형