CS/디자인패턴

[디자인패턴] Strategy 패턴 (전략 패턴)

mabb 2023. 6. 16. 17:25
반응형

▶디자인 패턴 ( Design Pattern)

:프로그램 개발 시 문제 해결을 위하여 빈번히 사용되는 개발자들의 경험, 내적인 축적에 대하여,
GoF(Gang of Four) 라 불리는 4인의 개발자들이 각각을 패턴으로 정의하고 이름을 붙였다.
이를 디자인 패턴 (Design Pattern) 이라고 한다.
 23개의 디자인 패턴을
『Elements of Reusable Object-Oriented Software』
라는 책으로 발간하였다.

Gang of Four 분들은 모두 안경을 썼다.

 

▷디자인 패턴의 용어를 빌리면 서로의 아이디어를 보다 용이하게 비교, 논의할 수 있게 된다.
▷재사용과 기능확장이 쉬운 소프트웨어를 만들기 위한 유익한 기법이 바로 디자인 패턴이다.

 

---------------------------------------------------------
1. Iterator
2. Adapter
3. Template Method
4. Factory Method
5. Singleton
6. Prototype
7. Builder
8. Abstract Factory
9. Bridge
10. Strategy
11. Composite
12. Decorator
13. Visitor
14. Chain of Responsibility
15. Facade
16. Mediator
17. Observer
18. Memento
19. State
20. Flyweight
21. Proxy
22. Command
23. Interpreter
---------------------------------------------------------

▶Strategy 패턴

"전략적으로 알고리즘을 교체"


-왜 사용하는가
-클래스다이어그램
-각 클래스(인터페이스)의 역할
-Java소스

▶Strategy 패턴에 대한 이해

- 프로그래밍에서 strategy = 전략 = 알고리즘

- 같은 문제를 다른 방법으로 해결하기 위한 '알고리즘 교체 전략'이 Strategy패턴이다.

- 가위바위보를 이기기 위한 전략을 전략 A, 전략 B, 전략 C... 등의 방법으로 교체한다.

- 보통은 알고리즘이 메소드 내부에 녹아 있는 경우가 많다.

- 알고리즘을 의식적으로 분리하고 알고리즘에 대한 인터페이스(API)를 규정한다.

- 규정한 알고리즘 인터페이스를 위임하여 이용한다.

- 위임이라는 느슨한 연결을 사용하여 알고리즘을 용이하게 교체할 수 있다.

- strategy 패턴에서 위임을 사용하여 런타임 중 전략을 교체할 수 있다.(동적인 교체) 

- 전략을 위임하는 곳을 교환하는 패턴이다.

-전략가는 '전략'을 가지고 있다. 전략가의 전략은 어떤 문제를 해결하기 위한 다양한 전략으로 구체화될 수 있다.

-예제에서는 랜덤으로 전략가에게 Integer배열, String배열, Double배열을 전해준다. 전략가는 Integer배열은 삽입정렬로, String배열은 선택정렬로, Double배열은 버블 정렬 알고리즘으로 오름차순 정렬한다.

 

▶왜 사용하는가

-어떠한 문제를 해결하기 위하여 알고리즘(전략)을 교체하기 위해 사용한다. 시스템이 느린 경우에 알맞은 알고리즘, 시스템이 빠른 경우에 알맞은 알고리즘 등을 런타임 중 동적으로 교체할 수 있다.
-메소드 내에 녹아 있는 알고리즘을 분리하여 관리하기 위해 사용한다. 알고리즘을 분리하면 알고리즘을 교체하기 쉬워진다.

 

▶클래스다이어그램

Strategy패턴의 클래스다이어그램

 

▶각 클래스(인터페이스)의 역할

 

▷추상적인 전략 역할

구체적인 전략들에 대한 인터페이스 역할이다. 전략가는 추상적인 전략을 가지고 있다.

▷구체적인 전략 역할

다양하게 구현되는 전략(알고리즘) 들이다. 어떠한 문제를 해결하기 위한 구체적인 방법 및 절차를 구현하여야 한다.

▷전략가 역할

전략가는 '추상적인 전략'을 가지고 어떠한 문제를 해결한다. 

▷Main 역할

전략가를 생성하고  전략 실행을 위한 메소드를 호출한다.

 

▶Java 소스

*java1.8 이전 버전을 사용하는 교재를 참고하였습니다.
Java API 문서 등을 참조하여 제네릭을 적용하는 등 소스를 개선할 필요가 있습니다.
(https://docs.oracle.com/en/java/javase/20/docs/api/)

▷Main.java

package main.java.designpattern.strategy2;

public class Main {
    public static void main(String[] args){

        Strategist sorter;
        Strategy strategy;

        Comparable[] paramArr;
        Integer[] intArr = {10,21,32,4,15,62,7};
        String[] strArr = {"홍길동","김민수","박철수","안정수"};
        Double[] doubleArr = {23.1,423.0,2.1,44.4};

        String str;
        int rand = (int)(Math.random()*10.0);
        if(rand % 3 == 0){
            paramArr = intArr;
            str = "main.java.designpattern.strategy2.ConcreteStrategy1";
        }else if(rand % 3 == 1){
            paramArr = strArr;
            str = "main.java.designpattern.strategy2.ConcreteStrategy2";
        }else{
            paramArr = doubleArr;
            str = "main.java.designpattern.strategy2.ConcreteStrategy3";
        }
        try {
            strategy = (Strategy)Class.forName(str).newInstance();
            sorter = new Strategist(strategy,paramArr);
            sorter.doSortAlgorithm();
            sorter.printArray();

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

 

▷Strategy.java

package main.java.designpattern.strategy2;

public interface Strategy {
    public  abstract <T extends Comparable> void sortAlgorithm(T[] array);
}

 

▷ConcreteStrategy1.java

package main.java.designpattern.strategy2;

public class ConcreteStrategy1 implements Strategy{
    @Override
    public <T extends Comparable> void sortAlgorithm(T[] array){
        //selectionSort
        System.out.println("선택정렬 실행");
        int min;
        for(int i=0; i<array.length; i++){
            min = i;
            for(int j=i+1; j<array.length; j++){
                if(array[j].compareTo(array[min]) < 0){
                    min = j;
                }
            }
            T tmp = array[i];
            array[i] = array[min];
            array[min] = tmp;
        }
    }
}

 

▷ConcreteStrategy2.java

package main.java.designpattern.strategy2;

public class ConcreteStrategy2 implements Strategy{
    @Override
    public <T extends Comparable> void sortAlgorithm(T[] array){
        //insertionSort
        System.out.println("삽입정렬 실행");
        for(int i = 1; i< array.length; i++){
            T tmp = array[i];
            int aux = i - 1;
            while( (aux >= 0) && (array[aux].compareTo(tmp) > 0)){
                array[aux + 1] = array[aux];
                aux --;
            }
            array[aux + 1] = tmp;
        }
    }
}

 

▷ConcreteStrategy3.java

package main.java.designpattern.strategy2;

public class ConcreteStrategy3 implements Strategy{
    @Override
    public <T extends Comparable> void sortAlgorithm(T[] array) {
        //BubbleSort
        System.out.println("버블정렬 실행");
        for(int i = 0; i < array.length; i++){
            for(int j = 1; j < array.length - i; j++){
                if(array[j].compareTo(array[j-1]) < 0){
                    T tmp = array[j];
                    array[j] = array[j-1];
                    array[j-1] = tmp;
                }
            }
        }
    }
}

 

▷ConcreteStrategy4.java - Strategy패턴에서는 전략가에게 네 번째 전략을 만들어 주는 것이 쉽다.

package main.java.designpattern.strategy2;

public class ConcreteStrategy4 implements Strategy{
    @Override
    public <T extends Comparable> void sortAlgorithm(T[] array) {

    }
}

 

▷Strategist.java

package main.java.designpattern.strategy2;

public class Strategist<T extends Comparable> {
    private Strategy strategy;
    private T[] arr;
    public Strategist(Strategy strategy, T[] arr){
        this.strategy = strategy;
        this.arr = arr;
    }
    public <T extends Comparable> void doSortAlgorithm(){
        strategy.sortAlgorithm(arr);
    }
    public void printArray(){
        for(T t:arr){
            System.out.print(t + " ");
        }
        System.out.println();
    }
}

 

소스의 수정 없이, 전략가에게 전해주는 배열의 종류에 따라 전략가는 다양한 정렬전략(알고리즘)을 구사한다.

---------------------------------------------------------
※참고자료
-Java언어로 배우는 디자인 패턴 입문
-Headfirst Design Pattern
-나무위키, 위키백과, 네이버백과
-리팩토링구루(https://refactoring.guru/ko)

반응형