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 패턴을 이해하는 목적의 코드이므로 간단하게 작성하였다.