들어가기 전에

확장에는 자유롭게 열려 있고 변경에는 굳게 닫혀 있다는 객체지향 설계의 핵심 원칙인 개방 폐쇄 원칙(OCP) 코드에서 어떤 부분은 변경을 통해 그 기능이 다양해지고 확장하려는 성질이 있고, 어떤 부분은 고정되어 있고 변하지 않으려는 성질이 있음을 말한다. 변화의 특성이 다른 부분을 구분해주고, 각각 다른 목적과 다른 이유에 의해 다른 시점에 독립적으로 변경될 수 있는 효율적인 구조를 만들어주는 것이 개방 폐쇄 원칙.

템플릿 메소드 패턴

슈퍼클래스에 기본적인 로직의 흐름(변하지 않는 부분)을 만들고, 그 기능의 일부(변하는 부분)를 추상 메소드나 오버라이딩 가능한 protected 메소드 등으로 만든 뒤 서브 클래스에서 이러한 메소드를 필요에 맞게 구현해서 사용하는 방법

  • 장점

    개방 폐쇄 원칙(OCP)를 지키는 구조가 된다.

  • 단점

    각기 다른 로직마다 상속을 통해 새로운 클래스를 만들어야 한다. 4개의 로직이 있으면 4개의 서브클래스를 만들어서 사용해야 한다.

    확장구조가 이미 클래스를 설계하는 시점에서 고정되어 컴파일 시점에 이미 그 관계가 결정되어 있다. 따라서 그 관계에 대한 유연성이 떨어져 버린다.

전략 패턴의 적용

개방 폐쇄 원칙을 잘 지키면서 템플릿 메소드 패턴보다 유연하고 확장성이 뛰어나다. 오브젝트를 아예 둘로 분리하고 클레스 레벨에서는 인터페이스를 통해서만 의존하도록 만든다.

복잡하지만 바뀌지 않는 일정한 패턴을 갖는 작업흐름이 존재하고 그중 일부분만 자주 바꿔서 사용해야하는 경우에 적합한 구조.

전략 패턴의 기본 구조에 익명 내부 클래스를 활용한 방식을 스프링에서는 템플릿/콜백 패턴이라고 한다. 전략 패턴의 컨텍스트를 템플릿, 익명 내부 클래스로 만들어지는 오브젝트를 콜백

템플릿이란

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

  • 템플릿은 어떤 목적을 위해 미리 만들어둔 모양이 있는 틀(도형자, 모양자)
  • 프로그래밍에서는 고정된 틀 안에 바꿀 수 있는 부분을 넣어서 사용하는 경우에 템플릿이라고 부른다.
  • JSP는 HTML이라는 고정된 부분에 EL과 스크립릿이라는 변하는 부분을 넣은 일종의 템플릿 파일
  • 템플릿 메소드 패턴은 고정된 틀의 로직을 가진 템플릿 메소드를 슈퍼클래스에 두고, 바뀌는 부분을 서브클래스의 메소드에 두는 구조로 이뤄진다.
  • 고정된 작업 흐름을 가진 코드를 재사용한다.

콜백이란

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

  • 템플릿 안에서 호출되는 것을 목적으로 만들어진 오브젝트

템플릿/콜백의 특징

  • 여러 개의 메소드를 가진 일반적인 인터페이스를 사용할 수 있는 전략 패턴의 전략과 달리 템플릿/콜백 패턴의 콜백은 보통 단일 메소드 인터페이스를 이용한다. (람다식) 왜냐하면 템플릿의 작업 흐름 중 특정 기능을 위해 한 번 호출되는 경우각 일반적이기 때문
  • 하나의 템플릿에서 여러 가지 종류의 전략이 필요하면 하나 이상의 콜백 오브젝트를 사용하기도 한다.
  • 콜백은 일반적으로 하나의 메소드를 가진 인터페이스를 구현한 익명 내부 클래스로 만들어진다.
  • 콜백 인터페이스의 메소드에는 보통 파라미터가 있다. 이는 템플릿의 작업 흐름 중에 만들어지는 컨텍스트 정보를 전달 받을 때 사용된다.

템플릿 콜백 클라이언트 그림

  • 클라이언트의 역할은 템플릿 안에서 실행될 로직을 담은 콜백 오브젝트를 만들고, 콜백이 참조할 정보를 제공하는 것이다. 만들어진 콜백은 클라이언트가 템플릿의 메소드를 호출할 때 파라미터로 전달된다.
  • 템플릿은 정해진 작업 흐름을 따라 작업을 진행하다가 내부에서 생성된 참조정보를 가지고 콜백 오브젝트의 메소드를 호출한다. 콜백은 클라이언트 메소드에 있는 정보와 템플릿이 제공한 참조정보를 이용해서 작업을 수행하고 그 결과를 다시 템플릿에 돌려준다.
  • 템플릿은 콜백이 돌려준 정보를 사용해서 작업을 마저 수행한다. 경우에 따라 최종결과를 클라이언트에 다시 돌려주기도 한다.
  • 템플릿/콜백 방식에서는 매번 메소드 단위로 사용할 오브젝트를 새롭게 DI한다.
  • 전략 패턴과 DI의 장점을 익명 내부 클래스 사용 전략과 결합한 독특한 활용법
  • 클라이언트가 오브젝트 팩토리 역할도 하는 수동 DI

출처

토비의 스프링(책)

댓글남기기