토비의 스프링 chaper 3 요약

Reading time ~4 minutes

토비의 스프링 chapter 3

어려운 토비의 스프링.. 1, 2장은 양은 많았지만 어느 정도 읽을 만 했지만 3장은 생각보다 더욱 안읽히는 것 같다. 이번 주 할당 받은 읽는 양은 3,4장이다. 개발도 시작하면서 더욱 읽을 시간은 없어졌고 기어코 마지막 날 까지 읽어야 하는 상황이 벌어졌다…

3장

3장은 템플릿에 관한 이야기이다. 1장 2장에서 개선의 개선을 거듭한 초난감 DAO를 가지고 좀더 발전시켜 나가본다. 앞서 작성한 코드에는 예외처리 부분이 상당히 빠져있다. 예외처리를 적용하기 위해 try-catch 문을 사용했다.

리소스의 반환

Conntection 이나 PreparedStatement 를 사용하고 마지막에 close() 를 통해 종료 시킨다. 의미로 봐서는 열린 객체를 닫는다 로 볼 수 있을 것 같은데 여기서 할당된 리소스를 반환하는 것이다. DB 커넥션이라는 제한적인 리소스를 공유해서 사용하는 서버에서는 이 리소스 반환이 필수적이다. 예외가 발생 했을때 반환하지 않으면 피명적인 문제를 일으킬 수도 있다.

새로 알게된 사실 close 또한 예외처리를 해줘야 한다.

connection c = null;
try {
    // ...
} catch (SQLException e) {
    // ...
} finally {
    if ( c != null ) {
        try {
            c.close() ;
        } catch (SQLException e) { }
    }
}

변하는 것과 변하지 않는 것

위에 적힌 코드를 보면 try-catch 문이 중첩에다가 if조건문도 있고 등등 난잡한 코드가 생겼다. 그리고 //.. 로 작성된 부분이 실제 Connection을 가지고 수행해야할 비즈니스 로직이라고 하면 이부분은 메소드 마다 다르게 구현될 것이다.

이 비즈니스 로직은 그럼 매번 바뀌는 것이고, 이외의 예외처리하는 부분은 매번 같을 것이다. 그러면 매번 같은 예외처리가 생길텐데 그 부분마다 계속 copy & paste 할 것인가? 그럼 안되지.. 그래서 적용할 패턴이 전략패턴 이다.

전략패턴 이외에도 적용할 만한 방법으로는 메소드 추출, 템플릿 메소드 패턴사용 등이 있지만 메소드 추출은 커다란 이득을 보지 못하고 바뀌는 부분을 추출해버리는 형태라 어색하다.

템플릿 메소드 패턴은 DAO 로직마다 상속을 통해 새로운 클래스를 만들어야하는 단점과, 컴파일 시점에 클래스간의 확장 구조, 관계가 결정되어버린다는 점, 상속을 이용하므로 유연하지 못한점이 단점이다.

전략패턴 : 오브젝트를 아예 둘로 분리하고 클래스 레벨에서는 인터페이스를 통해서만 의존하도록 만드는 패턴

클라이언트 (deleteAll) 에서 어떤 전략 쓸껀지 주입하게 하고, 컨텍스트에서는 주입받은 전략을 사용하면 돼. 그 전략은 인터페이스로 만들어져 있고 구현체마다 다른 로직을 가지고 있으면 되지.

마이크로 DI

DI : 제 3자의 도움을 통해 두 오브젝트 사이의 유연한 관계가 설정되도록 만든다는 것

일반적으로 DI 는 4개의 오브젝트 사이에서 일어난다. 관계를 가질 오브젝트 2개, 이 2개의 관계를 결정해주는 오브젝트 팩토리, 그리고 이걸 사용하는 클라이언트. 인데 때로는 오브젝트 팩토리의 역할을 클라이언트에서 책임질 수도 있다. 또한 클래스 내부에서 메소드로 결정되는 경우도 있고. 작은 단위에서 DI가 이루어지는 걸 마이크로 DI라고 한다.

중첩 클래스의 종류

중첩 클래스 : 다른 클래스 내부에 정의되는 클래스

  1. 스태틱 클래스 - 독립적으로 오브젝트로 만들어질 수 있음
  2. 내부 클래스 - 자신이 정의된 클래스의 오브젝트 안에서만 만들어질 수 있음 2-1. 멤버 내부 클래스 : 오브젝트 레벨에서 정의 2-2. 로컬 클래스 : 메소드 레벨에서 정의 2-3. 익명 내부 클래스 : 이름을 가지지 않음

특별한 DI

메소드 레벨의 DI 를 적용하고, 컨텍스트가 다른 DAO에서 사용할 수 있을 만큼 범용적인 일을 하므로 클래스로 분리했다. 그러고 DAO에서는 context를 주입 받고, context에서는 datasource를 주입받게만들어 datasource 와 dao 사이에 context가 끼어들어갔다. 근데 이 과정에서 DI 원칙을 역행하는 모습을 볼 수 있다.

앞서 진행한 DI는 관계를 유연하게 하기 위해 interface로 만들고 오브젝트간의 관계를 느슨하게 만들었다. 하지만 여기서는 클래스를 주입시켰다. 앞뒤가 안맞는다.

결론 부터 말하면 책에서는 꼭 그럴필요는 없다. 란다. DI의 의미를 정확하게 곱씹어 보면 객체의 생성과 관계 설정에 대한 제어권한을 오브젝트에서 제거하고 외부로 위임했다는 IoC 개념을 포괄한다고 한다. 그런 의미에서는 context는 스프링을 이용해 dao 객체에서 사용하게 주입했으니까 DI의 기본을 따른다고 한다.

어렵다…

스프링에서는 드물지만 클래스를 직접 의존하는 경우도 있다.

여기서 사용한 dao와 context는 매우 긴밀한 관계를 가지고 강하게 결합되었다. 그러니까 항상 함께 사용되고 dao가 바뀐다면 context도 몽땅 바뀌어야 한다. 어쨋든 엄청나게 끈끈한 사이라서 클래스 주입을 해도 된다고 판단했다 인데. 이렇게 판단, 구현 하긴 어려울 것 같다.

그리고 의문사항이 생기는데 1장에서 바뀌지 않는 코드는 없다고 했다. 그러니 인터페이스로 유연하게 대처하는 방식으로 시작하는게 무조건 옳다고 했다. 근데 여기서는 인터페이스를 굳이 안만들어도 된다고 한다. 여기도 앞뒤가 안맞는다? 라고 생각했는데 무슨 의도인지 알겠다.

코드를 이용한 수동 DI

context를 빈으로 등록하고 dao로 주입하는 거 말고 코드로 주입시킬 수도 있다. 근데 이 경우엔 빈으로 등록하려는 이유인 싱글톤으로 만들어지는 걸 포기해야한다. 그리고 누군가 context를 생성하고 초기화하는 작업을 코드로해야한다. 그러고 사용하는 datasource를 코드로 주입 받아야한다..

public class UserDao {
    private JdbcContext jdbcContext;

    public void setDataSource(DataSource dataSource) {
        this.jdbcContext = new jdbcContext();
        this.jdbcContext.setDataSource(dataSource);
        this.dataSource = dataSource;
    }
}
  빈 등록 코드 이용
장점 오브젝트간 실제 의존관계가 설정파일에 명확히 드러남 DI 원칙에 부합하지 않는 구체적인 클래스와 관계가 직접 노출됨
단점 관계가 외부로 드러나지 않는 점 빈으로 만들때의 이점을 누리지 못함(싱글톤), 부가적인 코드 필요

템플릿과 콜백

템플릿

어떤 목적을 위해 미리 만들어 둔 모양이 있는 틀 고정된 틀 안에 바꿀 수 있는 부분을 넣어서 사용하는 경우

우리가 사용하는 세계에서는 템플리 메소드를 슈퍼클래스에 두고, 바꿀 수 있는 부분을 넣고 그걸 서브클래스에서 구현해서 사용하는거에 적용할 수 있겠다.

콜백

실행되는 것을 목적으로 다른 오브젝트의 메소드에 전달되는 오브젝트를 말함

파라미터롤 전달되는 메소드. 이지만 자바는 파라미터로 메소드를 못 날리니까 객체를 하나 날리지.

템플릿 콜백 작업 흐름

클라이언트 -> 클라이언트 : 1. callback 생성
클라이언트 -> 템플릿 : 2. callback 전달/템플릿 호출
템플릿 -> 템플릿 : 3. workflow 시작, 4. 참조 정보 생성
템플릿 -> 콜백 : 5. callback 호출/ 정보 전달
콜백 -> 콜백 : 6. client 변수 참조, 7. 작업 수행
콜백 -> 템플릿 : 8. 작업 결과 전달
템플릿 -> 템플릿 : 9. workflow 진행, 10. workflow 마무리
템플릿 -> 클라이언트 : 11. 작업 결과 전달

템플릿과 콜백을 찾을 땐

변하는 코드의 경계를 찾고 그 경계를 사이에 두고 주고받는 일정한 정보가 있는지 확인


출처 :

  • 이 글은 이일민 지음의 ‘토비의 스프링 3.1 vol.1’ 을 읽고 작성되었습니다.

Dooray!

Dooray CalDav, IMAP 사용법 Continue reading

Vue.js

Published on February 10, 2018

Java_tuning5

Published on March 06, 2017