일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Kotlin
- OS
- 스트림
- 토비의 스프링
- K8s
- Real MySQL
- list
- Java
- thread
- Stack
- 쿠버네티스
- redis
- JPA
- mysql
- 자바 ORM 표준 JPA 프로그래밍
- 스프링
- GC
- IntellJ
- 토비의 스프링 정리
- SpringBoot
- 이스티오
- 자바
- 보조스트림
- spring
- gradle
- jvm
- MSA
- Stream
- 백준
- Collection
- Today
- Total
인생을 코딩하다.
[Java] Strategy Pattern(전략 패턴) 본문
디자인 패턴의 꽃이라고 하는 전략 패턴을 알아보자. 전략 패턴을 구성하는 세 요소는 꼭 기억해둬야 한다.
- 전략 메서드를 가진 전략 객체
- 전략 객체를 사용하는 컨텍스트(전략 객체의 사용자/소비자)
- 전략 객체를 생성해 컨텍스트에 주입하는 클라이언트(제3자, 전략 객체의 공급자)
- 즉, 클라이언트가 전략을 생성해 전략을 실행할 컨텍스트에 주입하는 패턴
전략 패턴이란?
동일 계열의 알고리즘을 정의하고, 각 알고리즘을 캡슐화하여 이들을 상호교환이 가능하도록 만든다. 알고리즘을 사용하는 클라이언트와 상관없이 독립적으로 알고리즘을 다양하게 변경할 수 있게 한다.
즉, 특정한 기능을 수행하는데 있어서 다양한 알고리즘이 적용될 수 있는 경우에 상황에 따라 필요한 알고리즘을 선택하여 해결할 수 있는 디자인 패턴이다.
trategy
- 사용할 행위를 추상화한 인터페이스
Concrete Strategy
- Strategy에서 명시한 행위를 구현한 클래스
Context
- 전략을 사용하는 역할
- 필요에 따라 전략을 바꿔 사용할 수 있음
클라이언트는 다양한 전략 중 하나를 선택해서 생성한 후 컨텍스트에 주입한다.
예를 보자.
군인이 있고 군인이 사용할 무기가 있다. 보급장교가 무기를 군인에게 지급해주면 군인은 주어진 무기에 따라전투를 수행한다. 이것을 전략 패턴에 따라 구분해보면 아래와 같이 된다.
- 무기 -> 전략
- 군인 -> 컨텍스트
- 보급 장교 -> 제 3자, 즉 클라이언트
먼저 다양한 전략을 공통된 방식으로 사용하기 위해 인터페이스를 정의한다.
package DesignPattern.strategyPattern;
public interface Strategy {
void runStrategy();
}
이제 다양한 전략, 즉 무기를 구현하자. 먼저 총이다.
package DesignPattern.strategyPattern;
public class StrategyGun implements Strategy {
@Override
public void runStrategy() {
// TODO Auto-generated method stub
System.out.println("탕! 타탕! 탕탕!");
}
이번에는 검이다.
package DesignPattern.strategyPattern;
public class StrategySword implements Strategy {
@Override
public void runStrategy() {
System.out.println("쳉.. 채쟁챙 챙챙");
}
}
마지막으로 활까지 구현해 보자.
package DesignPattern.strategyPattern;
public class StrategyBow implements Strategy{
@Override
public void runStrategy() {
System.out.println("슝..쐐액..쉑, 최종 병기");
}
}
이번에는 무기(전략)을 사용할 군인(컨텍스트)을 구현하자.
package DesignPattern.strategyPattern;
public class Soldier {
void runContext(Strategy strategy) {
System.out.println("전투 시작");
strategy.runStrategy();
System.out.println("전투 종료");
}
}
마지막으로 무기(전략)를조달(생성)해서 군인(컨텍스트)에게 지급(주입)해 줄 보급 장교(클라이언트, 제3자)를 구현하자.
package DesignPattern.strategyPattern;
public class Client {
public static void main(String[] args) {
Strategy strategy = null;
Soldier rambo = new Soldier();
// 총을 람보에게 전달해서 전투를 수행하게 한다.
strategy = new StrategyGun();
rambo.runContext(strategy);
System.out.println();
// 검을 람보에게 전달해서 전투를 수행하게 한다.
strategy = new StrategySword();
rambo.runContext(strategy);
System.out.println();
// 화을 람보에게 전달해서 전투를 수행하게 한다.
strategy = new StrategyBow();
rambo.runContext(strategy);
}
}
출력
위 처럼 전략을 다양하게 변경하면서 컨텍스트를 실행할 수 있다. 단일 상속만이 간으한 자바 언어에서는 상속이라는 제한이 있어 템플릿 메서드보다는 전략 패턴이 더 많이 활용된다.
전략 패턴의 클래스 다이어그램을 보면 개방 폐쇄 원칙(OCP)과 의존 역전 원칙(DIP)이 적용된 것을 짐작할 수 있다.
장점
- 재사용이 쉽기 때문에 코드의 중복이 적다.
- 확장과 유지보수가 쉽다.
단점
- 사용자는 각 전략이 어떻게 동작하는지 이해하고 사용해야 한다.
- Concrete Strategy 클래스는 Strategy 인터페이스의 정보를 공유하기 때문에 필요하지 않은 정보를 갖는 경우가 발생한다.
- 각 전략은 인터페이스를 구현하여 객체로 만들어지기 때문에 전략의 개수만큼 객체가 생성되어야 한다.
출처 :
'Java' 카테고리의 다른 글
[Java]프록시 패턴(Proxy Pattern) (0) | 2021.02.09 |
---|---|
[Java] 어댑터 패턴(Adapter Pattern) (0) | 2021.02.08 |
[Java] ConcurrentHashMap (0) | 2021.01.30 |
[Java] Fork Join Pool (0) | 2021.01.29 |
[Java] PriorityQueue(우선순위 큐) (0) | 2021.01.28 |