인생을 코딩하다.

[토비의 스프링 3장 정리] 템플릿 본문

Spring

[토비의 스프링 3장 정리] 템플릿

Hyung1 2021. 6. 4. 21:16
728x90
반응형

3장, 템플릿

템플릿이란 바뀌는 성질이 다른 코드 중에서 변경이 거의 일어나지 않으며 일정한 패턴으로 유지되는 특성을 가진 부분을 자유롭게 변경되는 성질을 가진 부분으로부터 독립시켜서 효과적으로 활용할 수 있도록 하는 방법이다.

p.210)

  • 오류가 날 때마다 미처 반환되지 못한 Connection이 계속 쌓이면 어느 순간에 커넥션 풀에 여유가 없어지고
    리소스가 모자란다는 심각한 오류를 내며 서버가 중단될 수 있다.

p.211)

  • Connection이나 PreparedStatment에는 close() 메소드가 있다. 보통 리소스를 반환한다는 의미로 이해하는 것이 좋다.
  • 보통 Pool 방식으로 운영된다. 미리 정해진 풀 안에 제한된 수의 리소스를 만들어 두고 필요할 때 이를 할당하고, 반환되면 다시 풀에 넣는 방식으로 운영된다.
  • 요청이 매우 많은 서버환경에서는 매번 새로운 리소스를 생성하는 대신 풀에 만들어둔 리소스를 돌려가며 사용하는 편이 훨씬 유리하다.
  • 대신, 사용한 리소스는 빠르게 반환해야 한다. 그렇지 않으면 풀에 있는 리소스가 고갈되고 결국 문제가 발생한다. close() 메소드는 사용한 리소스를 돌려주는 역할을 한다.

p.212)

  • null 상태의 변수에 close() 메소드를 호출하면 NullPointerException이 발생할 테니
    이럴 땐 close() 메소드를 호출하면 안된다.

p.218)

템플릿 메소드 패턴의 적용

  • 템플릿 메소드 패턴은 상속을 통해 기능을확장해서 사용하는 부분이다. 변하지 않는 부분은 슈퍼클래스에 두고 변하는 부분은 추상 메소드로 정의해둬서 서브클래스에서 오버라이드하여 새롭게 정의해 쓰도록 하는 것이다.

p.219)

  • 서브클래스들이 이미 클래스 레벨에서 컴파일 시점에 이미 그 관계가 결정되어 있다.따라서 그 관계에 대한 유연성이 떨어져 버린다. 상속을 통해 확장을 꾀하는 템플릿 메소드 패턴의 단점이 고스란히 드러난다.

전략 패턴의 적용

  • 오브젝트를 아예 둘로 분리하고 클래스 레벨에서는 인터페이스를 통해서만 의존하도록 만드는 전략 패턴이다. 전략 패턴은
    OCP 관점에서 보면 확장에 해당하는 변하는 부분을 별도의 클래스로 만들어 추상화된 인터페이스를 통해 위임하는 방식이다.
  • 특정 확장 기능은 전략 인터페이스를 통해 외부의 독립된 전략 클래스에 위임하는 것이다.

p.224)

마이크로 DI

  • DI의 가장 중요한 개념은 제3자의 도움을 통해 두 오브젝트 사이의 유연한 관계가 설정되도록 만든다는 것이다.
  • 이렇게 DI의 장점을 단순화해서 IoC 컨테이너의 도움 없이 코드 내에서 적용한 경우를 마이크로 DI라고도 한다.
    또는 코드에 의한 DI라는 의미로 수동 DI라고 부를 수도 있다.

p.228)

중첩 클래스의 종류

  • 다른 클래스 내부에 정의되는 클래스를 중첩(nested class) 클래스라고 한다. 중첩 클래스는 독립적 오브젝트로 만들어 질 수 있는
    스태틱 클래스와 자신이 정의된 클래스의 오브젝트 안에서만 만들어질 수 있는 내부 클래스로 구분된다.
  • 내부 클래스는 다시 범위에 따라 세 가지로 구분된다. 멤버 필드처럼 오브젝트 레벨에 정의되는 멤버 내부 클래스메소드 레벨
    정의되는 로컬 클래스, 그리고 이름을 갖지 않는 익명 내부 클래스다. 익명 내부 클래스의 범위는 선언된 위치에 따라서 다르다.

로컬 클래스에는 여러 장점이 있다.

  • 메소드 안에 로컬클래스를 집어 넣음으로써 마치 로컬 변수를 선언하듯이 선언할 수 있다. 덕분에 클래스 파일이 하나 줄고, 메소드 안에서
    PreparedStatement 생성 로직을 함께 볼 수 있으니 코드를 이해하기도 좋다.
  • 로컬 클래스는 클래스가 내부 클래스이기 때문에 자신이 선언된 곳의 정보에 접근할 수 있다.
    • 다만 내부 클래스에서 외부의 변수를 사용할때는 외부 변수는 반드시 final로 선언해줘야 한다. user 파라미터는 메소드 내부에서 뱐경될 일이 없으므로 final로 선언해도 무방하다.
  • 메소드마다 추가해야 했던 클래스 파일을 하나 줄일 수 있다는 것도 장점이고 내부 클래스의 특징을 이용해 로컬 변수를 바로 가져다 쓸 수 있다는 것도 큰 장점이다.

p.230)

익명 내부 클래스

  • 클래스 생성과 오브젝트 생성이 결합된 형태로 만들어지며, 상속한 클래스나 구현할 인터페이스를 생성자 대신 사용해서 다음과 같은 형태로 만들어 사용한다. 클래스를 재사용할 필요가 없고, 구현한 인터페이스 타입으로만 사용할 경우에 유용하다.

익명 내부 클래스는 선언과 동시에 오브젝트를 생성한다. 이름이 없기 때문에 클래스 자신의 타입을 가질 수 없고, 구현한 인터페이스 타입의 변수에만 저장할 수 있다.

p.236)

스프링 빈으로 DI

  • jdbcContext는 DataSource와 달리 테스트에서도 다른 구현으로 대체해서 사용할 이유가 없다. 이런 경우는 굳이 인터페이스를 두지 말고 강력한 결합을 가진 관계를 허용하면서 위에서 마한 두 가지 이유인, 싱글톤으로 만드는 것과 JdbcContext에 대한 DI 필요성을 위해 스프링의 빈으로 등록해서 UserDao에 DI 되도록 만들어도 좋다.

p.237)

코드를 이용하는 수동 DI

  • 하나의 jdbcContext 오브젝트를 갖고 있게 하는 것이다. DAO 메소드에서 매번 만들어 사용한다면 수만, 수백만의 JdbcContext 오브젝트 가 만들어 지겠지만, DAO마다 하나씩만 만든다면 기껏해야 DAO 개수만큼, 웬만큼 대형 프로젝트라고 하더라도 수백 개면 충분할 것이다.
  • JdbcContext는 다른 빈을 인터페이스를 통해 간접적으로 의존하고 있다. 다른 빈을 의존하고 있다면, 의존 오브젝트를 DI를 통해 제공받기 위해서라도 자신도 빈으로 등록돼야 한다고 했다.

p.240)

템플릿과 콜백

전략 패턴의 컨텍스트를 템플릿이라 부르고, 익명 내부 클래스로 만들어지는 오브젝트를 콜백이라고 부른다

템플릿

  • 프로그래밍에서는 고정된 틀 안에 바꿀 수 있는 부분을 넣어서 사용하는 경우에 템플릿이라고 부른다.
  • 템플릿 메소드 패턴은 고정된 틀의 로직을 가진 템플릿 메소드를 슈퍼클래스에 두고, 바끼는 부븐을 서브클래스의 메소드에
    두는 구조로 이뤄진다.

콜백

  • 콜백은 실행되는 것을 목적으로 다른 오브젝트의 메소드에 전달되는 오브젝트를 말한다. 파라미터로 전달되지만 값을 참조하기 위한
    것이 아니라 특정 로직을 담은 메소드를 실행시키기 위해 사용한다.
  • 자바에선 메소드 자체를 파라미터로 전달할 방법은 없기 때문에 메소드가 담긴 오브젝트를 전달해야 한다. 그래서
    펑셔널 오브젝트라고도 한다.

템플릿/콜백의 동작 원리

  • 템플릿은 고정된 작업 흐름을 가진 코드를 재사용한다는 의미에서 붙인 이름이다. 콜백은 템플릿 안에서 호출되는 것을 목적으로 만들어진 오브젝트를 말한다.

템플릿/콜백 특징

  • 템플릿/콜백 패턴은 보통 단일 메소드 인터페으스를 사용한다. 템플릿의 작업 흐름 중 특정 기능을 위해 한 번 호출되는 경우가 일반적이기 떄문이다.
  • 하나의 템플릿에서 여러 가지 종류의 전략을 사용해야 한다면 하나 이상의 콜백 오브텍트를 사용할 수도 있다.
  • 콜백은 일반적으로 하나의 메소드를 가진 인터페이스를 구현한 익명 내부 클래스로 만들어진다고 보면 된다.
  • 콜백 인터페이스의 메소드에는 보통 파라미터가 있다. 이 파라미터는 템플릿의 작업 흐름 중에 만들어지는 컨텍스트 정보를 전달받을 때 사용된다.
  • 템플릿/콜백 방식에서는 매번 메소드 단위로 사용할 오브젝트를 새롭게 전달받는다는 것이 특징이다. 콜백 오브젝트가 내부 클래스로서 자신을 생성한 클라이언트 메소드 내의 정보를 직접 참조한다는 것도 템플리/콜백의 고유한 특징이다.

p.247)

  • 일반적으로는 성격이 다른 코드들은 가능한 한 분리하는 편이 낫지만, 이 경우는 반대다. 하나의 목적을 위해 서로 긴밀하게 연합되어 동작하는 응집력이 강한 코드들이기 떄문에 한 군데 모여 있는게 유리하다.

고정된 작업 흐름을 갖고 있으면서 여기저기서 자주 반복되는 코드가 있다면, 중복되는 코드를 분리할 방법을 생각해보는 습관을 기르자.

  • 중복된 코드는 먼저 메소드로 분리하는 간단한 시도를 해본다. 그 중 일부 작업을 필요에 따라 바꾸어 사용해야 한다면 인터페이스를 사이에 두고 분리해서 전략 패턴을 적용하고 DI로 의존관계를 관리하도록 만든다.
  • 그런데 바뀌는 부분이 한 애플리케이션 안에서 동시에 여러 종류가 만들어 질 수 있다면 이번에 템플릿/콜백 패턴을 적용하는 거을
     려해 볼 수 있다.

p.257)

코드의 특성이 바뀌는 경계를 잘 살피고 그것을 인터페이스를 사용해서 분리한다는, 가장 기본적인 객체지향 원칙에만 충실하면 어렵지 않게 템플릿/콜백 패턴을 만들어 활용할 수 있을 것이다.

 

제네릭스를 이용한 콜백 인터페이스

  • 결과의 타입을 다양하게 가져가고 싶다면, 자바 언어에 타입 파라미터라는 개념을 도입한 제네릭스를 이용하면 된다.
  • 제네릭스를 이용하면 다양한 오브젝트 타입을 지원하는 인터페이스나 메소드를 정의할 수 있다.
728x90
반응형
Comments