인프런 강의 [스프링 핵심 원리 - 고급편] 강의를 기반으로 작성한 글 입니다.
[Spring] Template Method 정의 및 사용
이전 글에 Template Method를 이용해서 상속을 이용해서 템플릿을 생성했었다.
템플릿의 생성으로 반복되는 부분의 로직을 하나로 묶을 수 있었지만
부모 클래스가 변경되면 자식 클래스의 변경이 될 수도 있어서 상속의 문제가 발생했다.
그래서 추상 클래스가 아닌 인터페이스를 구현하는 방식으로 변경하는 전략 패턴을 사용하고자 한다.
전략 패턴은 변하지 않는 부분은 Context에 둔다. 그리고, 변하는 부분을 Strategy Interface로 둔다.
그런 후, Interface를 구현하는 방식으로 사용한다. 상속이 아닌 위임으로 문제를 해결하는 방식이다.
이 주제를 공부하면서, 위임 개념이 생소했다. 위임을 조금 더 알아보자.
위임은 어떤 기능을 자신이 처리하지 않고 다른 객체에 위임시켜 그 객체가 일을 처리하도록 하는 것이다.
조금 더 생각해보자.
Template Method는 직접 추상 메소드를 통해서 구현해야 했다.
하지만, Strategy Pattern은 인터페이스에게 구현을 위임한다. 앞으로 나올 것이다.
그래서 Context
라는 곳에 변하지 않는 부분을 두고, 변하는 부분은 인터페이스에게 위임하는 것이다.
이렇게 되면 각기 다른 인터페이스 구현체를 갈아끼우기만 하면 편리하게 사용이 가능하다.
또한 역할을 분담했으니, Template Method에 비해 결합도도 더 낮아진다.
전략 패턴 | 템플릿 메소드 패턴 |
---|---|
![]() | ![]() |
전략 패턴은 인터페이스의 구현체가 아무리 변경되어도, 기존의 Context에 아무런 영향을 주지 않는다.
머리로는 이해가 가긴 하지만, 예시를 찾아보려 했었다. 하지만, 쉽지 않았다..
Context
에 다음과 같이 선언이 가능하다.
execute
를 변경되지 않는 코드를 작성하고 변경되는 부분은 인터페이스로 구현이 가능하다.
템플릿 메소드와 비교해보자.
전략 패턴 | 템플릿 메소드 패턴 |
---|---|
![]() | ![]() |
사실 이렇게 보면 크게 다른 점이 없다.
인터페이스로 구현한 것과, 추상 메소드로 구현한 점이 차이가 크게 없다.
하지만 역할이 분리된 것을 강조하며 생각하자.
또한 전략 패턴은 보다보니, Spring 의존 관계 주입과 굉장히 흡사한 형태를 띄고 있다.
실제로 의존 관계 주입에서도 전략 패턴을 사용한다고 한다.
선 조립, 후 사용의 관계를 가지고 있다.
생성자에 상속 받은 StrategyLogic1
클래스를 전달하고 있다.
익명 함수로 생성하여 생성자에 전달 중이다.
내부에 바로 익명함수를 생성하여 전달 중이다.
인터페이스 메소드가 하나라면 이렇게 람다 함수로 전달할 수 있다.
이 생성자 방식들은 싱글톤으로 하면 동시성 오류를 고려해야할 수도 있다.
왜냐면, 이 방식은 선 조립, 후 사용이기 때문이다.
이미 조립된 부분을 setter
로 변경하는 코드를 추가할 수도 있겠지만, 동시성 오류를 고려해야한다.
그래서 생성자 방식은 각자 하나씩 생성하는 것이 마음 편하다.
하지만, 메소드가 바뀔 때마다 인스턴스를 생성하면 그것도 메모리에 부담이 될 수도 있다.
파라미터 방식은 선 사용, 후 조립이다.
메소드를 호출 할 때, 조립하게 되는 것이다.
이렇게 되면 싱글톤 객체를 생성해서 변경된 인터페이스 구현체만 넘겨줘도 동시성 오류를 고민하지 않아도 된다.
파라미터로 전달하는 방식은 execute
메소드에 interface
를 전달하고 있다.
간단하게 람다함수만 살펴보면, 기존에 생성자 방식이 아닌, execute
에 함수를 전달하는 방식이다.
이렇게 생성 인스턴스를 줄이고 메모리를 줄일 수 있다.