개발을 하다보면 여러 클래스에서 공통적으로 사용되는 코드와 각 클래스마다 다른 구현 사항이 섞여있는 경우를 종종 볼 수 있다. 이 경우 중복되는 코드가 발생하고, 유지∙보수가 힘들어진다. 따라서 문제점을 해결하기 위해 우리는 변하는 코드와 변하지 않는 코드를 분리 할 필요가 있다.
문제는 변하는 코드가 변하지 않는 코드 중간에 섞여있다면 단순히 메서드로 추출하는 것이 어려운 경우가 있는데, 다음의 패턴들을 통해 해결할 수 있다.
Template Method Pattern
템플릿 메서드 패턴은 공통으로 사용되는(변하지 않는) 메서드를 상위 클래스에서 구현하여 템플릿화 하고, 세부 동작은(변하는 코드) 이를 사용하는 하위 클래스에서 각각 다르게 구현하는 패턴이다
AbstractTemplate는 공통으로 사용되는 코드(변하지 않는 코드)를 정의한 execute() 메서드와, 자식 클래스에서 세부 동작을 구현할 call() 메서드가 존재한다.
템플릿 메서드 패턴을 적용할 하위 클래스는, AbstractTemplate 클래스를 상속한 이후 call() 메서드만 재정의 하면 된다. 이후 템플릿의 execute()를 실행하여 공통 메서드와 세부 메서드를 모두 실행시킬 수 있다
구현
다음처럼 사용할 수 있다
장단점
- 장점
- 상위 클래스에서 로직을 공통화 하여 코드의 중복을 줄일 수 있다
- 한번의 변경 사항으로, 공통된 로직을 사용하는 모든 클래스에게 변경 사항을 적용시킬 수 있다. 또한 이러한 변경이, 각 클래스의 다른 로직에게 미치는 영향을 최소화 시킬 수 있다
- 단점
- 상속을 사용하기 때문에 상속의 단점을 그대로 가져가서 유연성이 떨어지며, 로직이 복잡하면 템플릿 형태를 유지하기 어려워진다
- 상위 클래스에서 추상 메서드가 많아지면, 클래스의 생성 및 관리가 어려워 질 수 있다
- 상위 클래스를 수정할 때, 서브 클래스에서 영향을 받을 수도 있다
Strategy Pattern
전략 패턴(Strategy Pattern)은 템플릿 메서드 패턴에서 변경되는 로직을 Interface로 정의하고 완전히 분리한 후, 이를 유연하게 갈아 끼울 수 있도록 만든 패턴으로, 템플릿 메서드 패턴에서 상속의 단점을 제거한 패턴이다. 여기서 전략(Strategy)는 템플릿 메서드 패턴에서 추상 메서드를 의미한다.
전략 패턴에서는 공통으로 사용되는(변하지 않는) 메서드를 Context에서 구현하고, 세부 동작(변하는 메서드)을 Strategy라는 인터페이스에 정의한다. 이후 구현체에서 세부 동작을 구현하여 문제를 해결한다.
상속을 사용하던 코드를 인터페이스로 바꾼 후 유연성이 높아지고 결합도가 낮아져서 Starategy와 Context는 코드 변경시 서로 영향을 받지 않고, 필요에 따라서 자유롭게 다른 Startegy를 사용할 수 있다.
이때 Strategy는 필드값으로 주입받아 사용 하는 방법(선 조립, 후 실행)과 파라미터로 넘겨받는 방법이 있다
구현
Template Callback Pattern
템플릿 콜백 패턴 이전에, 콜백이 무엇인지 알아보자
Callback (Call-after function)
- 콜백(콜애프터 함수)란, 다른 메서드의 인수로 넘겨주는 실행 가능한 코드를 말한다
- ex) Strategy Pattern의 ContextV2에서 인수로 넘어오는 Strategy가 callback이 된다
- call(호출)-back(뒤) 이므로 코드가 호출은 되지만, 실행 시점이 넘겨준 곳의 뒤에서 실행된다는 뜻이다
- 콜백을 넘겨받아 실행하는 코드(메서드)는, 콜백을 즉시 실행할 수도 있고 나중에 실행할 수도 있다
- Java에서의 Callback
- Java에서는 인수로 객체를 넘겨줘야 한다
- Java 8 이전에는 보통 하나의 메서드를 가진 인터페이스를 구현한 후, 익명 내부 클래스를 인수로 넘겼다
- Java 8부터는 Lmabda를 사용할 수 있고, 최근에는 주로 Lambda를 사용한다
이처럼 콜백 패턴은 그냥 어떤 메서드를 실행할 때, 인수로 다른 객체를 넘겨준다고 생각하면 된다. 그렇다면 템플릿 콜백 패턴은 어떤것일까?
Template Callback Pattern(템플릿 콜백 패턴)
- GOF 패턴이 아닌 스프링 내부에서 자주 사용하는 패턴으로, 스프링 안에서만 말하는 패턴이다. Strategy Pattern의 일부로, Template과 Callback이 강조된 패턴이라고 생각하면 된다
- Strategy Pattern(전략 패턴)중 ContextV2와 같이 콜백을 넘겨주는 방식으로 Context가 Template 역할을, Starategy가 Callback 역할을 한다
- 스프링 내부에서 JdbcTemplate, RestTemplate, TransactionTemplate, RedisTemplate처럼 다양한 템플릿 콜백 패턴이 사용된다. 스프링에서 xxxTemplate이 있다면 대부분이 템플릿 콜백 패턴으로 구현되었다고 생각하면 된다
Reference
- 템플릿 메소드 패턴 - 완벽 마스터하기: https://inpa.tistory.com/entry/GOF-%F0%9F%92%A0-%ED%85%9C%ED%94%8C%EB%A6%BF-%EB%A9%94%EC%86%8C%EB%93%9CTemplate-Method-%ED%8C%A8%ED%84%B4-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EC%9E%90
- 스프링 핵심 원리 - 고급편(김영한): https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B3%A0%EA%B8%89%ED%8E%B8
- [디자인 패턴] 템플릿 메서드 패턴/전략 패턴/템플릿 콜백 패턴: https://velog.io/@codemcd/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-%ED%85%9C%ED%94%8C%EB%A6%BF-%EB%A9%94%EC%84%9C%EB%93%9C-%ED%8C%A8%ED%84%B4%EC%A0%84%EB%9E%B5-%ED%8C%A8%ED%84%B4%ED%85%9C%ED%94%8C%EB%A6%BF-%EC%BD%9C%EB%B0%B1-%ED%8C%A8%ED%84%B4