Intro

  • 토비의 스프링 1장 (오브젝트와 의존관계)를 학습한 후 작성한 리뷰입니다.

객체지향적인 코드를 위해서…

  • 1장에서는 정리되지 않은 코드를 객체지향적인 설계를 통해 어떻게 하면 유연하고 확장성 있는 코드를 작성할 것인지에 대해 단계적으로 설명하고 있습니다.
  • 책에서는 DAO와 DB connection에 관한 예제를 들었는데, 더 이해하기 쉽게 연극(로미오와 줄리엣)에 관한 예제로 바꾸었습니다.

초기 코드

  • Romeo.java
public class Romeo {

    private Juliet juliet = new Juliet1();

    public void acting() {
        System.out.println("줄리엣 역을 맡은 " + juliet.getName() + " 님과 같이 공연합니다.");
    }

    public static void main(String[] args) {
        Romeo romeo = new Romeo();
        romeo.acting();
    }

}
  • Juliet.java
public interface Juliet {
    String getName();
}
  • Juliet1.java
public class Juliet1 implements Juliet{

    @Override
    public String getName() {
        return "김태희";
    }

}
  • Juliet2.java
public class Juliet2 implements Juliet{

    @Override
    public String getName() {
        return "전지현";
    }

}

초기 구조

구조1

초기 코드의 문제점?

위의 구조의 문제점은 무엇일까요?
Romeo 코드의 변경 없이는 Juliet 기능의 확장이 자유롭지 못하다는 것이 문제입니다.
즉, 내가 Juliet의 배역이 ‘김태희’ 에서 ‘전지현’ 으로 바뀐다면 Romeo의 코드 변경이 불가피 합니다.
이는, 좋은 객체지향의 설계가 아닙니다.
그렇다면 이런 문제가 발생하는 이유는 무엇일까요?
이유는 바로, Romeo 안에 분리되지 않은, 또 다른 관심사항이 존재하기 때문입니다.

문제 해결

그렇다면, 위에서 발생했던 문제를 어떻게 해결할 수 있을까요?
문제가 되는 부분은 Romeo.java의

Juliet juliet = new Juliet1();

부분 입니다. 구현체 (new Juliet1())에 의존하고 있다는 것이 문제입니다.
그렇다면, 이 의존성을 어떻게 제거할 수 있을까요?
바로, 의존성을 책임지는 별도의 클래스를 만드는 것입니다.
즉, Juliet의 배역을 결정해주는 별도의 클래스인 Director를 만들겠습니다.

개선 코드

  • Director.java
public class Director {

    public static void main(String[] args) {
        Romeo romeo = new Romeo(new Juliet1());
        romeo.acting();
    }

}
  • Romeo.java
public class Romeo {

    private Juliet juliet;

    public Romeo(Juliet juliet) {
        this.juliet = juliet;
    }

    public void acting() {
        System.out.println("줄리엣 역을 맡은 " + juliet.getName() + " 님과 같이 공연합니다.");
    }

}

나머지 코드는 개선전 코드와 동일

개선 후 구조

구조2

결과

  • 인터페이스와 관심사항의 분리를 통해서 객체 지향의 장점을 극대화 하였습니다.
  • 결과적으로 유연하고 확장성 있는 코드를 작성할 수 있었습니다.
  • 이후 내용에 대한 리뷰는 다음 포스트에서 진행하겠습니다.

참고

  • 에이콘/토비의 스프링 3.1 vol1/이일민 지음

댓글남기기