728x90

개념

SOLID 원칙 중 개방폐쇄의 원칙에 따라 확장에 대해서는 개방적이고 변경에 대해서는 폐쇄적으로

기존의 코드를 변경하지 않으면서 기능을 추가할 수 있도록 고안된 디자인 패턴이다.

 

변경될 것(전략)과 변하지 않는 것을 구분하여 두 모듈이 만나는 지점에 인터페이스를 정의해

인터페이스에 의존하도록 코드를 작성한다.

 

전략 패턴을 이용하는 역할을 수행하는 컨텍스트가 필요에 따라 구체적인 전략을 바꿀 수 있도록

의존관계를 주입하며, 전략은 인터페이스나 추상 클래스로 외부에서 동일한 방식으로 호출할 수 있게

하며, 콘크리트 전략은 전략을 실제로 구현한 클래스를 의미한다.

 

장점

  1. 알고리즘을 캡슐화해 실행 중에 동적으로 바꿀 수 있다.
  2. 새로운 변경이 기존의 코드에 영향을 미치지 않는다.
  3. 전략은 독립적으로 사용될 수 있어, 다른 클래스에서도 재사용할 수 있다.
  4. 독립적이기 때문에 테스트가 용이하다.
  5. 의존관계를 역전시켜 확장성 있는 코드를 만들 수 있다.
  6. 각 알고리즘을 별도의 클래스로 분리하여 코드를 읽기 쉽고 유지보수가 용이하다.

 

단점

  1. 전략 패턴을 사용할 때마다 새로운 구현 클래스를 만들어야 한다.
  2. 전략 패턴을 사용하기 위해 의존성을 주입해야 하기 때문에 과한 의존 관계가 형성 될 수 있다.
  3. 구현이 어려워 적절한 분석과 설계가 필요하다.
  4. 런타임 시에 알고리즘을 선택하기 때문에 추가적인 오버헤드가 발생할 수 있다.
  5. 추가적인 클래스와 인터페이스가 필요해 코드가 복잡해질 수 있다.

 

사용하는 이유

if (분기1) {

} else if (분기2) {

} else if (분기3) {

} else if (분기4) {
	// 만약 이 중간에 새로운 분기를 추가하거나
   	// 분기가 수십 수백가지라면?
} else if (분기5) {

} else if (분기6) {

} else if (분기7) {

}
...
else {

}

 

조건문을 사용한 분기처리는 변경과 확장 시 코드가 복잡해지고 수정이 불편하고 실수가 발생할 확률이 높다.

= 유지보수에 유리하지 않다.

 

알고리즘의 변경이 빈번한 경우에 전략 패턴을 사용해 효율적으로 적용할 수 있다.

 

예시

interface Strategy {
	do();
}
class ConcreteStrategyA implements Strategy {
	do();
}

class ConcreteStrategyZ implements Strategy {
	do();
}

...

class ConcreteStrategyZ implements Strategy {
	do();
}
class Context {
    Strategy strategy;

    void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }
	
    void do() {
        this.strategy.do();
    }
}

 

전략의 추상화와 이를 구현한 다양한 전략 구현 클래스

그리고 전략을 등록하고 실행하는 컨텍스트로 이루어져 있다.

 

기타

템플릿 메소드 패턴과의 차이점

  1. 전략 패턴은 컴포지션 방식을 템플릿 메소드 패턴은 상속을 사용한다.
  2. 전략 패턴은 알고리즘 자체를 캡슐화 한다면 템플릿 메서드 패턴은 알고리즘의 일부 단계만 변경한다.
  3. 전략 패턴은 실행 중에 동적으로 알고리즘 교환이 가능하지만 템플릿 메소드 패턴은 고정되어 있다.

 

'CS' 카테고리의 다른 글

CPU 작동 원리  (1) 2023.10.09
고정 소수점과 부동 소수점  (0) 2023.10.09
ARM 프로세서  (0) 2023.10.09

+ Recent posts