전략 패턴(Strategy Pattern)
각 객체들이 하게 될 행위에 대해 전략 클래스를 생성하고, 유사한 행위를 캡슐화하는 인터페이스를 정의하여, 객체의 행위를 동적으로 바꾸고 싶은 경우 직접 행위를 수정하지 않고, 전략(객체)을 바꿔주기만 함으로써 유연하게 확장하는 방법을 의미한다.
각 행위를 각각의 객체로 만들고, 행위의 변경이 필요한 경우 전략을 바꾸는 방식
UML
- Strategy: 외부에서 전략을 교체하는 인터페이스. 추상 메서드를 활용한다.
- ConcreteStrategyA/ConcreteStrategyB : 전략 객체
- Context: Strategy를 실제 주입받아 사용하는 객체전략 패턴(Strategy Pattern)
실 사용 예시
위의 구글 검색의 경우 전체/이미지/뉴스/동영상/지도 탭을 누를 때 마다 각각 정보를 보여주는 전략이 다르다. 이 5개의 탭을 교체하는게 Strategy가 되고 각각이 ConcreteStrategyA/B/C/D/E가 될 수 있다.
좋지 않은 코드 예시
class MainActivity : AppCompatActivity() {
private var mode = Mode.ALL //MODE {ALL,IMAGE,NEWS,MAP}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
serach_btn.setOnClickListener {
when(mode){
Mode.ALL -> {
//전체 검색하는 코드
}
Mode.IMAGE -> {
//이미지 검색하는 코드
}
Mode.NEWS -> {
//뉴스 검색하는 코드
}
Mode.MAP -> {
//지도 검색하는 코드
}
}
}
}
}
위의 경우 현재 어떤 탭이 클릭되었는지에 따라 when(switch)문으로 분기하여 서로 다른 알고리즘을 구현한다. 이 경우 전략이 늘어나거나 이와 비슷한 검색창이 다른 곳에서도 활용될 경우에 유연하지 못하다.
개선된 코드
공통 행위에 대한 인터페이스 지정 및 전략 별 클래스 생성
interface SearchStrategy{
fun search()
}
class AllSearchStrategy : SearchStrategy{
override fun search(){
//전체 검색 코드
}
}
class ImageSearchStrategy : SearchStrategy{
override fun search(){
//전체 검색 코드
}
}
class NewsSearchStrategy : SearchStrategy{
override fun search(){
//전체 검색 코드
}
}
class MapSearchStrategy : SearchStrategy{
override fun search(){
//전체 검색 코드
}
}
실제 사용
class MainActivity : AppCompatActivity() {
private var searchStrategy : SearchStrategy = AllSearchStrategy()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
searchStrategy.setSearchStrategy(ImageSearchStrategy)
serach_btn.setOnClickListener {
searchStrategy.search()
}
}
fun setSearchStrategy(_searchStrategy :SearchStrategy){
searchStrategy = _searchStrategy
}
}
위처럼 간단하게 인터페이스 클래스의 search() 메서드 호출을 통해 구현이 가능해졌다. 전체/이미지/뉴스 등 탭이 바뀔 경우 setSearchStrategy() 메서드를 통해 전략을 바꾸기만 하면 된다. 이후 학습할 상태 패턴과 다르게 전략 패턴은 외부 객체인 MainActivity에서 실행할 객체(전략)을 지정해준다. 상태 패턴은 수행할 객체(상태)가 내부에서 결정이 된다.
요약
- 각각 서로 다른 유사한 행위를 하는 코드가 존재할 경우 사용 가능
- 공통적인 행위를 정의한 인터페이스 클래스를 만든다
- 인터페이스 클래스를 상속받아 필수 메서드를 구현한다.
- Context에서는 인터페이스 클래스 타입의 변수를 선언하여 때에 따라 전략 객체를 교체하면서 실행한다.
'Domain > 디자인패턴' 카테고리의 다른 글
[디자인패턴] 템플릿 메소드 패턴(Template Method Pattern) (0) | 2021.03.30 |
---|---|
[디자인패턴] 상태 패턴(State Pattern) (0) | 2021.03.29 |
[디자인패턴] 어댑터 패턴(Adapter Pattern) (0) | 2021.03.28 |
[디자인패턴] 팩토리 패턴(Factory Pattern) (0) | 2021.03.27 |
[디자인패턴] 싱글톤 (Singleton) (0) | 2021.03.27 |