Strategy 패턴

5.디자인패턴 2016. 8. 15. 17:51

참고

- 상태와 행위의 결별


Strategy 패턴은 작업을 수행하는 대상 객체에 (변수 대신) 다른 객체를 인자로 넣어 줌으로써 대상 객체의 행위를 변경하는 패턴이다.


해결하고자 하는 문제

- 객체의 동작을 동적으로 변경하고자 한다.
- 객체의 동작이 다양하고 확장될 가능성이 있다.
- 상태 변수에 의해 조건문 중첩이 너무 많이 발생한다.

문제 코드

public static final int ADD_STATE = 0;

public static final int SUB_STATE = 1;

int static calculate(int state, int a, int b){

    if(state == ADD_STATE){

        return 5 + 10;

    }

    else if(state == SUB_STATE){

        return 5 - 10;

    }

    return 0;

}

public static void main(String[] args) {

    int result = 0;

    result = calculate(ADD_STATE, 5, 10);

    result = calculate(SUB_STATE, 5, 10);

}

위의 코드는 state 변수의 값에 따라서 간접적으로 calculate() 함수의 동작을 제어하도록 되어 있다. 상태 변수를 통해 행위를 변경시키는 코드는 좋은 코드가 아니다. 불필요한 상태 변수가 선언되고, if 문이나 switch 문과 같은 불필요한 제어문이 생성되기 때문이다. 가장 좋은 방법은 변경시키고자 하는 행위를 직접 넘겨주는 것이다.

우선 아래와 같이 변경하고자 하는 행위를 객체로 선언한다. 인자로 넘길 때 변경이 가능한 형태여야 하므로 동일한 인터페이스를 상속 받은 Add 클래스와 Sub 클래스를 선언해 준다.

interface IFunction{

    public int calculate(int a, int b);

}

class Add implements IFunction{

    public int calculate(int a, int b){

        return a + b;

    }

}

class Sub implements IFunction{

    public int calculate(int a, int b){

        return a - b;

    }

}


이렇게 선언된 클래스를 calculate() 함수가 인자로 받을 수 있도록 한다. 이 때 state 변수는 이제 필요 없으므로 제거한다.

static int calculate(IFunction function, int a, int b){

    return function.calculate(a, b);

}


public static void main(String[] args) {

    int result = 0;

    result = calculate(new Add(), 5, 10);

    result = calculate(new Sub(), 5, 10);

}


최종 결과

interface IFunction{

    public int calculate(int a, int b);

}

class Add implements IFunction{

    public int calculate(int a, int b){

        return a + b;

    }

}

class Sub implements IFunction{

    public int calculate(int a, int b){

        return a - b;

    }

}

public class Strategy {

    static int calculate(IFunction function, int a, int b){

        return function.calculate(a, b);

    }

    public static void main(String[] args) {

        int result = 0;

        result = calculate(new Add(), 5, 10);

        result = calculate(new Sub(), 5, 10);

    }

}


상태를 나타내는 state 변수 대신에 행위를 구현한 객체를 직접 넣어 줌으로써 코드가 더 간결해지게 된다.

Strategy 클래스의 calculate() 함수는 IFunction 타입의 객체를 인자로 받도록 되어 있다. main() 함수에서는 calculate() 함수를 통해서 실행하고자 하는 행위에 따라서 Add 클래스 혹은 Sub 클래스를 바꿔 넣어주면 행위가 변경된다.  



Posted by 이세영2
,