본문으로 바로가기

[디자인패턴] 전략패턴

category 나의 주니어 개발 일기/디자인패턴 2022. 10. 5. 16:58
728x90
반응형
SMALL

전략패턴

여러 알고리즘을 캡슐화하고 상호 교환 가능하게 만드는 패턴

파라미터에 따라서 어떤 분기를 작성하고 싶을때?

기존 코드를 변경하지 않고 새로운 분기만 추가하고 싶을때

open closed principal 을 지킨다.

  • **Context**

로직을 수행하는 클래스

public class BlueLightRedLight {
/*
    //1. 생성자로 전략을 주입 받는 첫번째 방법.
    private Speed speed;

    public BlueLightRedLight(Speed speed){
        this.speed = speed;
    }

    public void blueLight(){
        speed.blueLight();
    }

    public void redLight(){
        speed.redLight();
    }*/

    //2. 각각의 다양한 전략을 주입할 수 있는 두번째 방법.
    public void blueLight(Speed speed){
        speed.blueLight();
    }

    public void redLight(Speed speed){
        speed.redLight();
    }
}
  • **Strategy**

알고리즘 인터페이스

// <Strategy>
public interface Speed {

    void blueLight();

    void redLight();
}
  • **ConcreateStrategy**

각각의 알고리즘을 구현(**클라이언트가 직접 선택하여 적용**)

// <ConcreteStrategy>
public class Normal implements Speed{
    @Override
    public void blueLight() {
        System.out.println("2초 파란불");
    }

    @Override
    public void redLight() {
        System.out.println("2초 빨간불");
    }
}
// <ConcreteStrategy>
public class Faster implements Speed {
    @Override
    public void blueLight() {
        System.out.println("1초 파란불");
    }

    @Override
    public void redLight() {
        System.out.println("1초 빨간불");
    }
}
  • Client
public class Client {
    public static void main(String[] args){
        //1.생성자를 통한 전략 주입 new Normal()
    /*    BlueLightRedLight light = new BlueLightRedLight(new Normal());
        light.blueLight();
        light.redLight();  */

        //2. 각각의 다양한 전략을 주입할 수 있는 두번째 방법.
        BlueLightRedLight light = new BlueLightRedLight();
        light.blueLight(new Normal());

        //3. 익명 내부를 이용한 세번째 방법. -> 클래스를 안만들어도 됨
        light.redLight(new Speed() {
            @Override
            public void blueLight() {
                System.out.println("0.5초 익명 파란불");
            }

            @Override
            public void redLight() {
                System.out.println("0.5초 익명 빨간불");
            }
        });
    }
}

장단점

장점

기존코드를 변경하지 않고 새로운 전략 추가 가능

상속 대신 위임을 사용할 수 있음(상속은 하나밖에 안되고, 상속을 강요하면 정말 상속이 필요할때 상속을 못할수도 있음, 상속은 상위클래스가 변경되면 하위클래스가 변경됨)

런타임 중에 전략을 변경할 수 있음

 BlueLightRedLight light = new BlueLightRedLight();
        light.blueLight(new Normal());

        light.redLight(new Speed() {
            @Override
            public void blueLight() {
                System.out.println("0.5초 익명 파란불");
            }

            @Override
            public void redLight() {
                System.out.println("0.5초 익명 빨간불");
            }
        });

단점

클래스가 많이 늘어나고 복잡도가 증가한다.

(단 재사용이 많이 된다면, 클래스가 증가하지 않고 익명 내부로 구현하면 클래스의 개수를 줄일수 있기도 함)

**클라이언트가 구체적인 전략을 알아야 한다.**

실생활에 적용되있는 Strategy 패턴

1.자바) Comparator 인터페이스

public class StrategyInJava {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(10);
        numbers.add(5);

        System.out.println(numbers);

        //1
        Collections.sort(numbers);
        //2
        Collections.sort(numbers, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1-o2;
            }
        });
        //3
        Collections.sort(numbers,Collections.reverseOrder());
        System.out.println(numbers);
    }
}

2.스프링

너무 많지만 그중 한 예

public class StrategyInSpring {
    public static void main(String[] args) {
        ApplicationContext applicationContext1 = new ClassPathXmlApplicationContext();
        ApplicationContext applicationContext2 = new FileSystemXmlApplicationContext();
        ApplicationContext applicationContext3 = new AnnotationConfigApplicationContext();

        BeanDefinitionParser parser;

        PlatformTransactionManager platformTransactionManagerCustomizer;

        CacheManager cacheManager;
    }
}

해당 인프런 강의를 기반으로 작성 되었습니다.

https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4

728x90
반응형
LIST