전략패턴

전략패턴(strategy pattern) 또는 정책 패턴(policy pattern)이라고 하는데

 

실행 중에 알고리즘을 선택할 수 있게 하는 행위 디자인 패턴이다

 

- 특정한 계열의 알고리즘들을 정의하고

- 각 알고리즘을 캡슐화 하고

- 이 알고리즘들을 해당 계열 안에서 상호 교체가 가능하게 만든다

 

전략은 알고리즘을 사용하는 클라이언트와는 독립적으로 다양하게 만든다

 

쉽게 설명하면

각각의 알고리즘을 교환이 가능하도록 정의, 캡슐화 한 다음에

서로 교환해서 사용할 수 있는 패턴이다

즉 객체들이 할 수 있는 동작을 각각의 전략으로 만들어 놓고

동적으로 동작을 변경해야 한다면 전략만 변경하여 동작이 바뀌도록 하는 패턴이다

 

Context : Strategy의 메소드를 호출해서 사용하는 클래스

Strategy : 전략을 사용하기 위한 인터페이스

ConcreteStrategyA, B, C : Strategy 인터페이스를 실제 구현하는 클래스

 

전략 패턴 예시

아래와 같이 단순히 오버라이딩을 이용해서 울음메서드를 변경해서 오리와 사람을 구분한다면

나중에 사람이 진화해서 오리처럼 울수있게되었을때 메서드를 바꿔줘야하는 일이 생긴다

이러면 OCP 에 위배하고 시스템이 거대해 질 수록 유지보수하기 힘들어진다

public interface Sound {
    void cry();
}

public class Duck implements Sound {
    @Override
    public void cry() {
        System.out.println("꽉");
    }
}

public class Person implements Sound {
    @Override
    public void cry() {
        System.out.println("울지 않아");
    }
}

Quacker duck = new Duck();
Quacker person = new Person();

duck.cry();
person.cry();

 

이때 사용하는게 전략 패턴인데 일단은 아래와 같이 전략 클래스를 생성해준다

전략으로는 우는것과 울지않는것 두개로 나누어 준다

public interface SoundStrategy {
    void cry();
}

public class CryStrategy implements SoundStrategy {
    @Override
    public void cry() {
        System.out.println("꽉");
    }
}

public class NoCryStrategy implements SoundStrategy {
    @Override
    public void cry() {
        System.out.println("울지않아");
    }
}

 

그리고는 전략을 호출하는 CryingContext를 만들어서 전략이 어떤것이 들어오느냐에 따라서

해당 전략으로 생성되는 메서드를 만들어 놓는다

public class CryingContext {
    private SoundStrategy soundStrategy;

    public void cry() {
        soundStrategy.cry();
    }

    public void setSoundStrategy(SoundStrategy soundStrategy) {
        this.soundStrategy = soundStrategy;
    }
}

public class Person extends CryingContext {
    public Person() {
        System.out.println("나는 사람");
    }
}

public class Duck extends CryingContext {
    public Duck() {
        System.out.println("나는 오리");
    }
}

 

그리고는 아래와 같이 진행해 보면 OCP를 위배하지 않으면서 사람도 오리처럼 울 수 있게 되었다

CryingContext person = new Person();
CryingContext duck = new Duck();
// 나는 사람
// 나는 오리

person.setSoundStrategy(new NoCryStrategy());
duck.setSoundStrategy(new CryStrategy());

person.cry();
duck.cry();
// 울지않아
// 꽉

// 사람이 드디어 오리처럼 울 수 있음
person.setSoundStrategy(new CryStrategy());
person.cry();
// 꽉