[오브젝트] 유연한 설계

woohobi·2022년 1월 27일
0

Book Review

목록 보기
5/5

유연한 설계

개방 폐쇄 원칙(OCP)

확장 가능하고 변화에 유연한 설계를 위해 확장에 열려 있어야하고, 수정에 대해서 닫혀 있어야 한다.

이를 위해서는 구현에 의존하지 않고, 역할(인터페이스)에 의존해야 한다. 즉, 런타임 의존성을 확장할 수 있으면서 컴파일 타임의 의존성은 유지해야 한다. 이는 추상화에 의존해야 한다는 의존성 역전 원칙(Dependency Inversion Principle, DIP)과도 이어진다.

의존성 주입(Dependency injection)

public class Movie{
    
    private DiscountPolicy discountpolicy;
    //의존성을 직접 생성하는 방식
    public Movie(){
        this.discountpolicy= new DiscountPolicy();
    }
    //외부에서 의존성을 주입하는 방식
    public Movie(DiscountPolicy discountpolicy){
        this.discountpoliy = discountpolicy;
    }
}

의존성을 직접 객체에서 생성하는 방식은 OCP를 위반할 뿐 아니라, 객체간의 과도한 결합도를 야기하기 때문에 DIP 도 위반한다. 좀 더 합리적인 방식은 외부에서 의존성을 주입해줌으로써, 객체의 생성과 사용을 분리할 수 있고, 객체간의 결합도의 의존도를 낮출 수 있다.

의존성 주입방식은 크게 2가지가 있다.

  • 생성자 주입 방식
  • setter
  • method 주입 방식
    나는 대체로 생성자 주입방식을 선호한다. 주입해야되는 객체를 setter 혹은, method을 통해 주입하지 않음으로써 생길 수 있는 NullPointerException 으로 발생할 수 있는 문제를 방지할 수 있고, Runtime 시점에 setter를 통해 잘못된 객체 의존이 생길 수 있음을 방지할 수 있다. 또한 테스트 코드 작성에도 생성자 주입방식이 더욱 유리하다.

의존성 역전 원칙과 패키지

객체지향 프로그래밍 언어에서 구성요소의 소유권을 결정하는 것은 모듈(패키지, 네임스페이스)이다. 유지보수 관점에서, 클래스 수정에 따라 패키지 전체가 재배포, 재컴파일 되어야 함으로 불필요한 클래스를 하나의 패키지에 두는 것은 빌드시간을 가파르게 상승시킨다.

하나의 정답 모듈구조는 없다고 생각한다. 프로젝트 규모에 따라서, 유연하게 모듈 구조를 가져갈 수 있어야 한다.

추상화의 트레이드 오프

앞서 추상화를 통해 OCP, DIP를 만족시키고 이로 인해 많은 편리함을 얻을 수 있었다. 하지만, 우리는 추상화는 추상화가 만드는 복잡성을 생각하고 유연함과 복잡함의 트레이드오프를 이해하고 적절한 설계를 할 수 있어야 한다.

profile
CDD - Coffee Driven Development

0개의 댓글