본문 바로가기
개념

[패턴] 전략 패턴(Strategy Pattern)

by hs_seo 2015. 7. 6.

 

전략 패턴, 스트래티지 패턴(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