전략 패턴, 스트래티지 패턴(Strategy Pattern)
전략 패턴에서는 알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만든다.
알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경할 수 있다.
클래스안에서 동작하는 것들을 멤버함수로 설정하지 않고, 클래스로 별도로 생성하여 처리하는 것
* 알고리즘(메소드) 부분만 변경하여 하나의 클래스가 여러가지 행동을 할 수 있도록 설정하는 것
예제코드
import java.util.ArrayList;
import java.util.List;
public class StrategyPatternWiki {
public static void main(String[] args) {
Customer a = new Customer(new NormalStrategy());
// Normal billing
a.add(1.0, 1);
// Start Happy Hour
a.setStrategy(new HappyHourStrategy());
a.add(1.0, 2);
// New Customer
Customer b = new Customer(new HappyHourStrategy());
b.add(0.8, 1);
// The Customer pays
a.printBill();
// End Happy Hour
b.setStrategy(new NormalStrategy());
b.add(1.3, 2);
b.add(2.5, 1);
b.printBill();
}
}
class Customer {
private List<Double> drinks;
private BillingStrategy strategy;
public Customer(BillingStrategy strategy) {
this.drinks = new ArrayList<Double>();
this.strategy = strategy;
}
public void add(double price, int quantity) {
drinks.add(strategy.getActPrice(price * quantity));
}
// Payment of bill
public void printBill() {
double sum = 0;
for (Double i : drinks) {
sum += i;
}
System.out.println("Total due: " + sum);
drinks.clear();
}
// Set Strategy
public void setStrategy(BillingStrategy strategy) {
this.strategy = strategy;
}
}
interface BillingStrategy {
double getActPrice(double rawPrice);
}
// Normal billing strategy (unchanged price)
class NormalStrategy implements BillingStrategy {
@Override
public double getActPrice(double rawPrice) {
return rawPrice;
}
}
// Strategy for Happy hour (50% discount)
class HappyHourStrategy implements BillingStrategy {
@Override
public double getActPrice(double rawPrice) {
return rawPrice * 0.5;
}
}
<JDK 8버전 - 람다식 >
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public class StrategyPatternInJDK8 {
static final Function<Double, Double> normal = (rawPrice) -> rawPrice;
static final Function<Double, Double> happyHour = (rawPrice) -> rawPrice * 0.5;
public static void main(String[] args) {
Customer2 a = new Customer2(normal);
// Normal billing
a.add(1.0, 1);
// Start Happy Hour
a.setStrategy(happyHour);
a.add(1.0, 2);
a.printBill();
// New Customer
Customer2 b = new Customer2(happyHour);
b.add(0.8, 1);
// End Happy Hour
b.setStrategy((rawPrice) -> rawPrice);
b.add(1.3, 2);
b.add(2.5, 1);
b.printBill();
}
}
class Customer2 {
private List<Double> drinks;
private Function<Double, Double> strategy;
public Customer2(Function<Double, Double> strategy) {
this.drinks = new ArrayList<Double>();
this.strategy = strategy;
}
public void add(double price, int quantity) {
drinks.add(strategy.apply(price * quantity));
}
// Payment of bill
public void printBill() {
double sum = 0;
for (Double i : drinks) {
sum += i;
}
System.out.println("Total due: " + sum);
drinks.clear();
}
// Set Strategy
public void setStrategy(Function<Double, Double> strategy) {
this.strategy = strategy;
}
}
디자인 원칙
애플리케이션에서 달라지는 부분을 찾아내고, 달라지지 않는 부분을 분리시킨다.
바뀌는 부분만 뽑아서 캡슐화 한다.
참고
https://en.wikipedia.org/wiki/Strategy_pattern
https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html
반응형
'개념' 카테고리의 다른 글
| C10K 문제(C10K problem) (0) | 2016.01.22 |
|---|---|
| [개념] REPL (0) | 2015.07.20 |
| [개념] NPAPI (0) | 2015.07.01 |
| [스크랩] GMT, UTC, KST (0) | 2015.06.18 |
| [스크랩] 리눅스와 유닉스 (0) | 2015.06.11 |