본문 바로가기

언어/JAVA

strategy pattern

객체지향의 5원칙 중 하나로 개방폐쇄의 원칙이 있다. "소프트웨어의 구성요소들은 확장에는 열려있어야하고, 변경에는 닫혀있어야한다."는 원칙이다. 기존 구성요소의 수정은 최소화하되 확장에는 적극적이여야한다는 말이다. 

결합도가 낮다는 의미다.

보면 클라이언트는 doSomething이라는 interface를 사용하며, 구현 class를 직접 사용하지 않는다. 이렇게 함으로써 결합도를 낮출 수 있고 만약 새로운 구현이 필요하다면 우리는 Abstraction라는 Instance를 상속받은 Class를 하나 더 만들어 사용하면 됩니다.

 

 

예시

// 다양한 무기(전략)를 공통된 방식으로 사용하기 위해 인터페이스 정의!!! (아주 중요)
interface Strategy {
   public abstract void runStrategy(); // 전략 메서드
}

// 다양한 전략, 즉 무기를 구현하자. 먼저 총이다.
class StrategyGun implements Strategy {
   @Override
   public void runStrategy() {
      System.out.println("탕, 타당, 타다당");
   }
}

// 이번에는 검(전략)이다.
class StrategySword implements Strategy {
   @Override
   public void runStrategy() {
      System.out.println("챙.. 채쟁챙 챙챙");
   }
}

// 마지막으로 활(전략)이다.
class StrategyBow implements Strategy {
   @Override
   public void runStrategy() {
      System.out.println("슝.. 쐐액.. 쉑, 최종 병기");
   }
}

// 이번에는 무기(전략)를 사용할 군인(컨텍스트)을 구현하자.
class Solider {
   void runContext(Strategy strategy) {
      System.out.println("전투 시작");
      strategy.runStrategy();
      System.out.println("전투 종료");
   }
}

// 마지막으로 무기(전략)를 조달(생성)해서 군인(컨텍스트)에게 지급(주입)해 줄 보급장교(클라이언트, 제3자)를 구현하자.
public class Client {
   public static void main(String[] args) {
      Strategy strategy = null;
      Solider rambo = new Solider;  // 컨텍스트 생성

      // 총(전략)을 람보(컨텍스트)에게 전달해서 전투를 수행하게 한다.
      strategy = new StrategyGun(); // 전략 생성
      rambo.runContext(strategy);   // 컨텍스트에게 전략 전달 및 사용
      System.out.println();

      // 검(전략)을 람보(컨텍스트)에게 전달해서 전투를 수행하게 한다.
      strategy = new StrategySword();  // 전략 생성
      rambo.runContext(strategy);      // 컨텍스트에게 전략 전달 및 사용
      System.out.println();

      // 활(전략)을 람보(컨텍스트)에게 전달해서 전투를 수행하게 한다.
      strategy = new StrategyBow();    // 전략 생성
      rambo.runContext(strategy);      // 컨텍스트에게 전략 전달 및 사용
   }
}
/* 실행결과
전투시작
탕, 타당, 타다당
전투종료

전투시작
챙.. 채쟁챙 챙챙
전투종료

전투시작
슝.. 쐐액.. 쇅, 최종 병기
전투종료
*/

위의 코드처럼 전략을 다양하게 변경하면서 컨텍스트를 실행할 수 있다. 전략 패턴은 다양한 곳에서 다양한 문제 상황의 해결책으로 사용되기 떄문에 디자인 패턴의 꽃이라고 불리운다.

 

그리고 템플릿 메서드 패턴과 굉장히 유사한 것을 알 수있다. 같은 문제의 해결책으로 상속을 이용하는 템플릿메소드 패턴과 객체 주입을 통한 전략패턴 중에서 선택해서 적용시킬 수 있다. 다만 단일상속만이 가능한 자바언어 특성상 상송이라는 제한이 있는 템플릿 메서드 패턴보다는 전락패턴이 더 많이 활용된다.

 

스프링 부트에서 환경세팅부분에 많은부분이 전략패턴으로 사용되었다.

 

 

 

 

참고

https://imbf.github.io/spring/2020/03/18/Spring-Design-Pattern(3).html

https://sabarada.tistory.com/32?category=800572

'언어 > JAVA' 카테고리의 다른 글

SingleTon Pattern  (0) 2022.02.15
정적 멤버 클래스 vs 비정적 멤버 클래스  (0) 2022.02.07
Adapter Pattern  (0) 2022.01.21
[UML]클래스 다이어그램  (0) 2022.01.19
다이아몬드 상속 문제(다중상속의 문제점)  (0) 2022.01.19