Strategy Pattern
Strategy Pattern
quote wiki
The strategy pattern (also known as the policy pattern) is a behavioral software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use. (wiki)
public class ScoreProcessing {
private int min, max ;
private float average ;
public void analyze(int[] data) {
min = max = data[0] ;
int sum = data[0] ;
for ( int i = 1 ; i < data.length ; i ++ ) {
if ( min > data[i] ) min = data[i] ;
if ( max < data[i] ) max = data[i] ;
sum += data[i] ;
}
average = (float) sum / data.length ;
}
public int getMin() { return min; }
public int getMax() { return max; }
public float getAverage() { return average; }
}
There is a problem in code. analyze function has a lot of functions. We need to split min, max.
splitting function also has a problem. Because
별도의 메소드로 min, max 를 빼더라도 문제가 있다. 왜냐면 알고리즘을 바꿀 때 많은 코드 변화를 초래한다.
그래서 Strategy Pattern 을 써야 한다.
import java.util.*;
interface Statistics {
public int getMax(int[] data);
public int getMin(int[] data);
public float getAverage(int[] data);
}
class GeneralStatistics
implements Statistics {
public int getMax(int[] data) {
int max = data[0] ;
for ( int i = 1 ; i < data.length ; i ++ )
if ( max < data[i] ) max = data[i] ;
return max ;
}
public int getMin(int[] data) {
int min = data[0] ;
for ( int i = 1 ; i < data.length ; i ++ )
if ( min > data[i] ) min = data[i] ;
return min ;
}
public float getAverage(int[] data) {
int sum = data[0] ;
for ( int i = 1 ; i < data.length ; i ++ )
sum += data[i] ;
float average = (float) sum / data.length ;
return average ;
}
}
class JavaStatistics
implements Statistics {
public int getMax(int[] data) {
int[] copied = Arrays.copyOf(data, data.length) ;
Arrays.sort(copied) ;
int max = copied[copied.length-1] ;
return max ;
}
public int getMin(int[] data) {
int[] copied = Arrays.copyOf(data, data.length) ;
Arrays.sort(copied) ;
int min = copied[0] ;
return min ;
}
public float getAverage(int[] data) {
int sum = getSum(data);
float average = (float) sum / data.length ;
return average ;
}
private int getSum(int[] data) {
int sum =0 ;
for ( int v : data ) sum += v ;
return sum;
}
}
class ScoreProcessing {
private Statistics statistics ;
private int min, max ;
private float average ;
public ScoreProcessing(Statistics statistics){
this.statistics = statistics;
}
public void analyze(int[] data) {
min = statistics.getMin(data);
max = statistics.getMax(data);
average = statistics.getAverage(data);
}
public int getMin() { return min; }
public int getMax() { return max; }
public float getAverage() { return average; }
}
public class Main {
public static void main(String[] args) {
int[] data = {0, 50, 10, 30, 70} ;
Statistics generalStatistics = new GeneralStatistics();
ScoreProcessing proc1 = new ScoreProcessing(generalStatistics) ;
proc1.analyze(data) ;
System.out.println(proc1.getMin()) ;
System.out.println(proc1.getMax()) ;
System.out.println(proc1.getAverage()) ;
// int[] data = {0, 50, 10, 30, 70} ;
Statistics javaStatistics = new JavaStatistics() ;
ScoreProcessing proc2 = new ScoreProcessing(javaStatistics) ;
proc2.analyze(data) ;
System.out.println(proc2.getMin()) ;
System.out.println(proc2.getMax()) ;
System.out.println(proc2.getAverage()) ;
}
}
Statistics 인터페이스를 GeneralStatistics, JavaStatistics 가 구현하는 형태다.
Statistics interface 는 min, max 만 정의하고 있지 구체적인 방법은 서술하지 않고 있다. 자세한 알고리즘의 선택은 implements 하는 클래스의 몫으로 남기는 것이다.
그리고 ScoreProcessing 가 Statistics 를 멤버로 가지고 있으면서 추후에 원하는 구현체를 set 하는 방식으로 작성한다.
설명보다 코드를 보는게 나을거라 본다.