-
[Spring] 전략 패턴 - 상속이 아닌 위임을 활용Spring 2022. 6. 15. 03:29
이전에 정리하였던 템플릿 메서드 패턴의 경우
변하지 않는 템플릿을 부모 클래스에 두고 변하는 부분은 자식 클래스에 두어서
상속을 활용하였다.
전략패턴에서는 상속이 아니라 변하지 않는 부분을 클래스로 두고 변하는 부분을 인터페이스로 만든 다음
해당 인터페이스를 구현하도록 하여서 문제를 해결한다.
전략 패턴의 의도(indent)는 아래와 같다
알고리즘 제품군을 정의하고 각각을 캡슐화하여 상호 교환하게 만들자.
전략을 사용하면 알고리즘을 사용하는 클라이언트와 독립적으로 알고리즘을 변경할 수 있다.전략패턴에서 변하지 않는 로직을 가지고 있는, 템플릿 역할을 하는 코드를 컨텍스트라고 한다.
해당 컨텍스트 안에서 인터페이스를 구현한 부분을 통해 일부 전략이 변경된다.
즉 컨텍스트 내부에는 해당 인터페이스를 필드를 가지고 있는 데, 이 필드에
인터페이스의 구현체를 주입하면 되는 것이다.
따라서 인터페이스의 구현체가 변경되거나 새로만들어져도 템플릿 코드에는 영향을 주지 않는다.
(스프링에서 의존관계 주입에 사용하는 방식이 전략 패턴이다.)
전략 패턴의 경우 이전 템플릿 메서드 패턴과 동일하게 익명 내부 클래스를 생성할 수 있고
컨텍스트의 생성자에서 바로 생성하여 전달해줄 수 있다.
이때 인터페이스에 메서드가 1개만 있다면 람다로 변경하여 작성할 수 있다.
지금까지 정리한 전략패턴은 스프링으로 애플리케이션 개발 시
로딩 시점에 의존관계를 주입하여 모두 맺어주고 나서 요청을 처리하는 것과 같은 원리이다.
하지만 이는 컨텍스트와 전략이 조립된 이후 변경하기 까다롭고 컨텍스트를 싱글톤으로 사용시
동시성 이슈 등 고려해야할 점이 많다.
이와 같은 경우 이전 컨텍스트 필드에 인터페이스 구현체를 주입하는 방식에서
파라미터로 직접 전달하여 사용하는 방식으로 변경하여 사용할 수 있다.
이에 따르면 컨텍스트는 실행될 때마다 전략을 인수로 전달받기 때문에
클라이언트는 원하는 전략을 컨텍스트를 실행할 때 전달할 수 있다. (유연성을 가지게 된다.)
이러한 방법도 물론 익명 내부 클래스를 사용가능하며 인터페이스 메서드가 1개일 경우
람다를 사용할 수 있다.
하지만 실행 때마다 전략을 계속 지정해주어야한다는 단점을 가지고 있다.
2번째 방법에 따르면 변하지 않는 템플릿 역할을 하는 컨텍스트에
변하는 부분인 전략(인터페이스 구현체)를 인수로 전달 받아 코드를 실행한다
이와 같이 다른 코드의 인수로서 넘겨주는 실행 가능한 코드를 콜백이라고 한다.
스프링에서는 위의 2번째와 같은 전략 패턴을 템플릿 콜백 패턴이라고 한다.
컨텍스트가 템플릿, 인터페이스 부분이 콜백이 되는 것이다.
(...Template가 있다면 템플릿 콜백 패턴으로 만들어져 있다고 보면 된다.)
콜백을 사용할 경우, 콜백 부분을 익명 내부 클래스나 람다를 사용하는 것이 편하다.
또한 여러 곳에서 함께 사용되는 경우 재사용을 위해 콜백을 별도의 클래스로 만들어도 된다.
이러한 템플릿 콜백 패턴을 사용해도 결국 원본 코드를 수정하는 문제와
적용이 필요한 클래스 갯수 만큼 작업을 해야한다는 문제는 그대로이다.
이를 해결하기 위한 방법은 이후 추가 공부 이후 정리하도록 하겠다.
[참고 : 인프런 - 스프링 핵심 원리 - 고급편]
'Spring' 카테고리의 다른 글
[Spring] 프록시 패턴과 데코레이터 패턴 - 3 (0) 2022.06.16 [Spring] 프록시 패턴과 데코레이터 패턴 - 2 (0) 2022.06.16 [Spring] 프록시 패턴과 데코레이터 패턴 - 1 (0) 2022.06.16 [Spring] 템플릿 메서드 패턴 - 변하는 것과 변하지 않는 것의 분리 (0) 2022.06.15 [Spring] 동시성 문제 해결하기 - ThreadLocal (0) 2022.06.14