둘셋 개발!

[Java] 디자인패턴 (1) - Strategy 패턴 본문

카테고리 없음

[Java] 디자인패턴 (1) - Strategy 패턴

23 2024. 2. 14. 22:02

전략 패턴이란?

한 기능을 수행하기 위한 전략이 여러개일 때, 각 전략을 캡슐화하여 런타임 시에 상호교체를 가능할 수 있게 하는 행위 디자인 패턴

 

이 패턴을 사용하는 이유는 OCP원칙(개방-폐쇄 원칙)을 지킬 수 있기 때문이다.

변경하는 부분을 찾아 캡슐화해서, 확장(전략 변경)에는 열려있고 수정(전략을 사용하는 코드또는 전략 코드)에는 닫혀있게 하는 것이다.

 

이는 전략이 빈번하게 변경되어 미리 정의해놓은 전략을 선택해야 하는 상황에서 유용하다.

 

 

(출처: https://velog.io/@hero6027/Strategy%EC%A0%84%EB%9E%B5-Pattern)

 

- Client: 서비스 이용자

- Context: 전략을 바탕으로 서비스를 제공하는 자

- Strategy: 전략 인터페이스

- ImplA, ImplB: 전략 구현체

 

여기서 Context는 구현체(ImplA와 ImplB)를 참조하는 것이 아니라 그들의 인터페이스(Strategy)를 참조하고 있다.

따라서 구현체를 교체해야 하는 상황이 발생하더라도 Context와 전략 구현체를 코드를 크게 변경하지 않아도 된다.


예시

('프리온본딩 2024년 2월 백엔드'에서 수업 중 진행했던 예시입니다)

 

요구사항: 매년 마다 사과를 품질을 나누는 기준이 달라짐. 런타임시 기준이 바뀌어도 코드를 수정하지 않고 교체가능하도록 구현하라

 

- ApplePredicate

사과의 품질을 나누는 추상화 클래스

(getFilterName()을 구현체들이 공통을 가져야 하기 때문에 추상화 클래스로 두고 filter() 부분을 추상화 메서드로 둠)

전략 인터페이스

- AppleColorPredicate

사과의 색깔로 품질을 나누는 구현체

전략 구현체 1

- AppleHeavyWeightPredicate

사과의 무게로 품질을 나누는 구현체

전략 구현체2

 

그리고 이 구현체를 런타임 시 선택하는 팩토리 클래스가 필요하다. 

 

-> applePredicateSet에 있는 ApplePredicate의 구현체를 의존성 주입 후에 Map 구조인 predicate에 (이름, 인스턴스)로 put한 후런타임 시 findBy를 통해 '필터이름'으로 인스턴스를 얻어 갈 수 있다.

스프링 대단.....

 

 

 

클래스 다이어그램으로 정리하자면 다음과 같다.