Strategy (전략 패턴)
04 Apr 2019 | design pattern programming softwareStrategy Pattern
전략이라는 의미이다.
특정 문제를 해결하기 위하여 알고리즘을 구현한 부분을 모두 교환할 필요가 있을때 사용한다.
예) 게임 가위바위보에서 가위/바위/보를 내는 전략 변경
예를 들어 출퇴근을 하는데 간단하게 가장 환승이 적은 전략 / 가장 빨리 가는 전략 / 랜덤으로 선택하여 가는 전략을 프로그래밍 해보겠다.
public class Main {
public static void main(String[] args) {
Employee employee = new Employee("Ran", new MinTransferStrategy());
Transport transport = employee.getMethod(100, 200);
System.out.println("MinTransferStrategy() : " + transport);
employee = new Employee("Ran", new FastestStrategy());
transport = employee.getMethod(100, 200);
System.out.println("FastestStrategy() : " + transport);
employee = new Employee("Ran", new RandomStrategy());
transport = employee.getMethod(100, 200);
System.out.println("RandomStrategy() : " + transport);
}
}
Employee Ran은 3번 출근을 하는데 각각 다른 전략을 선택한다. 적은 환승 / 빠른 길 / 랜덤 전략
public class Employee {
private String name;
private Strategy strategy;
public Employee(String name, Strategy strategy) {
this.name = name;
this.strategy = strategy;
}
public Transport getMethod(int startCode, int endCode) {
return strategy.getMethod(startCode, endCode);
}
}
public interface Strategy {
Transport getMethod(int startCode, int endCode);
}
전략의 인터페이스. 하나의 메소드를 가지고 있고 출발 위치와 도착 위치 코드를 가지고 있다.
public class FastestStrategy implements Strategy {
@Override
public Transport getMethod(int startCode, int endCode) {
return Transport.getFastestTransport(startCode, endCode);
}
}
public class MinTransferStrategy implements Strategy {
@Override
public Transport getMethod(int startCode, int endCode) {
return Transport.getComfortTransport(startCode, endCode);
}
}
각각의 전략 인터페이스를 구현한 구현 클래스. 전략에 따라 각각 필요한 메소드를 호출한다.
public class RandomStrategy implements Strategy {
private Random random = new Random();
@Override
public Transport getMethod(int startCode, int endCode) {
int n = random.nextInt(4);
return Transport.getTransport(n);
}
}
랜덤 전략은 말그대로 아무거나 선택한다.
public class Transport {
public static final int TRANSPORT_WALK = 0;
public static final int TRANSPORT_BUS = 1;
public static final int TRANSPORT_METRO = 2;
public static final int TRANSPORT_BIKE = 3;
private int currentTransport;
public static final Transport[] transports = {
new Transport(TRANSPORT_WALK),
new Transport(TRANSPORT_BUS),
new Transport(TRANSPORT_METRO),
new Transport(TRANSPORT_BIKE),
};
public Transport(int num) {
currentTransport = num;
}
public static Transport getTransport(int n) {
return transports[n];
}
public static int getTotalTimeUsingTransport(int n, int startCode, int endCode) {
switch (n) {
case TRANSPORT_WALK:
return 200;
case TRANSPORT_BUS:
return 100;
case TRANSPORT_METRO:
return 150;
case TRANSPORT_BIKE:
return 180;
}
return 0;
}
public static int getTotalTransferUsingTransport(int n, int startCode, int endCode) {
switch (n) {
case TRANSPORT_WALK:
return 0;
case TRANSPORT_BUS:
return 3;
case TRANSPORT_METRO:
return 2;
case TRANSPORT_BIKE:
return 1;
}
return 0;
}
// get fast way
public static Transport getFastestTransport(int startCode, int endCode) {
int minimumIndex = -1;
int min = 999;
for(int i =0; i < 4; i++) {
int n = getTotalTimeUsingTransport(i, startCode, endCode);
if(n < min) {
min = n;
minimumIndex = i;
}
}
return Transport.getTransport(minimumIndex);
}
// get minimum transfer way
public static Transport getComfortTransport(int startCode, int endCode) {
int minimumIndex = -1;
int min = 999;
for(int i =0; i < 4; i++) {
int n = getTotalTransferUsingTransport(i, startCode, endCode);
if(n < min) {
min = n;
minimumIndex = i;
}
}
return Transport.getTransport(minimumIndex);
}
@Override
public String toString() {
return "Transport{" + "currentTransport=" + currentTransport + '}';
}
}
교통편에 따라 달라지는 시간 또는 환승 개수를 리턴한다.
실제로 이런 프로그램을 구현한다면 startCode와 endCode에 따라 달라지는 시간을 가져오도록
서버에서 API를 호출해야 하겠지만 strategy 패턴을 이해하는 목적의 코드이므로 간단하게 작성하였다.