전략 패턴 (Strategy Pattern)

김대경·2022년 4월 20일
0

주의사항!

공부하며 작성한 포스트입니다. 틀린 내용이나 부실한 설명이 있다면 알려주세요.😁


전략 패턴 또는 정책 패턴은 실행 중에 알고리즘을 선택할 수 있게 하는 행위 소프트웨어 디자인 패턴이다. 전략 패턴은 특정한 계열의 알고리즘들을 정의하고 각 알고리즘을 캡슐화하며 이 알고리즘들을 해당 계열 안에서 상호 교체가 가능하게 만든다. - 위키백과

개요


전략 패턴은 프로그램 또는 소스코드 진행 중에 알고리즘을 선택할 수 있게 하기 위한 디자인 패턴입니다. 전략 패턴을 적용하면, 사전에 정의하고 캡슐화 한 알고리즘을 개발자가 원하는 영역 안에서 교체 및 선택할수 있습니다. 한마디로, 특정 영역 안에서 알고리즘을 선택하여 적용할 수 있게 하는 설계 방법입니다.

예시

한 건물안에 자판기가 있습니다. 이 자판기는 버튼을 누르면 해당 버튼에 알맞는 음료를 뽑아줍니다.


전략 패턴 적용 전

public class DrinkMachine{
	public DrinkMachine(String button){
    	String drink;
    	if(button == "탄산"){
        	drink = "탄산음료";
        }else if(button == "이온음료"){
        	drink = "이온음료";
        }else{
        	drink = "물";
        }
        return drink;
    }
}

위의 코드에서 알 수 있듯, 전략 패턴을 사용하지 않는다면 if-else블럭으로 코드를 제어해야 합니다. 이는 코드의 유연성을 떨어뜨리고 하나의 메소드에 너무 많은 로직을 추가해야 합니다. 여기서 자판기의 음료가 추가되어 커피, 과일주스가 추가된다고 가정 해 봅시다.
그렇다면 위의 코드에서 커피, 과일주스에 대한 if-else코드블럭이 추가로 작성되어야 할 것이고, 이처럼 간단한 코드가 아닌 100줄, 1000줄 짜리 복잡한 로직이라면 Copy-Paste가 거의 불가능할것입니다.

전략 패턴 적용 후

다음과 같이 음료 종류를 인터페이스화 하고 이를 구현해보겠습니다.

public interface Beverage{
	void vend();
}
public class Soda implements Beverage{
	private final String DRNIK = "탄산음료";
    @override
    public void vend(){
    	return DRINK;
    }
}
public class Coffee implements Beverage{
	private final String DRINK = "커피";
    @override
    public void vend(){
    	return DRINK;
    }

위와 같이 음료를 하나의 클래스로 만들고, 이 클래스들을 자판기에 붙이도록 하겠습니다.

public class VendingMachine{
	public String vend(Beverage beverage){
    	return beverage.vend();
    }
}
public class Building{
	public static void main(String[] args){
    	VendingMachine vendingMachine = new VendingMachine();
        // 자판기 설치.
        String soda = vendingMachine.vend(sodaButton());
        // soda 버튼을 누르면 탄산음료 추출.
        String coffee = vendingMachine.vend(coffeeButton());
        // coffee 버튼을 누르면 커피 추출.
    }
    
    public static Beverage sodaButton(){
    	return new Soda();
    }
    
    public static Beverage coffeeButton(){
    	return new Coffee();
    }
}

이제 자판기에 추가하고자 하는 메뉴 혹은 교체하고자 하는 메뉴가 있다면, 음료를 만들고(알고리즘 정의)하고 누르는 버튼(전략)만 다르게 주면 됩니다. 이처럼 각각의 영역에 다른 전략을 취하는 방법을 전략 패턴이라 합니다.

코드 수정이 발생했을 때
전략패턴을 적용하지 않았을 때 >> if-else블럭 추가
전략패턴 적용 시 >> Class 추가

장점

전략 패턴의 장점


첫 번째는 기존 메소드의 직접적인 수정 없이 새로운 알고리즘을 추가할 수 있다는 것입니다.(OCP원칙)
두 번째는 유지보수에 장점이 있습니다. 위 코드에서 새로운 메뉴를 추가하고 기존에 있던 메뉴를 변경하게 된다해도 기존에 있던 코드는 변함이 없습니다. 하지만 전략패턴을 사용하지 않은 코드에서는 기존에 있던 코드를 수정해야겠죠?

예시를 든 코드는 아주 간단해서 사실 전략패턴이 필요 없지만, 만약 실제 프로젝트에서 1000줄짜리, 2000줄짜리 코드의 분기가 일어난다면 유지보수에 있어서 리스크가 더 클수밖에 없습니다.

단점

장점만 있는 기술은 존재하지 않습니다.


알고리즘이 다수 있는 프로그램은 전략패턴보다 일반적인 if-else구문이 보기에 더 편하고 깔끔할 수 있습니다. 즉, 모든 상황에서 사용되는 만능 코드는 아니라는 것입니다. 극단적인 예를들어, 알고리즘의 변화가 없고 사용하는 영역이 하나라면 굳이 전략패턴을 사용할 필요 없이 바로 적용하면 되겠죠? 단순한 프로그램에 적용할수록, 오히려 코드의 복잡도는 더 올라갈 수 있습니다.

결론


전략 패턴은 클라이언트의 요구사항 변경 및 다양한 영역에서의 여러가지 알고리즘을 적용할 때 사용하면 빛을 발하는 패턴입니다. 모든 상황에서 통용되는 만능 기법은 물론 아니며, 상황에 따라 어떤 패턴을 사용하고 무슨 기법을 적용할지는 오롯이 개발자의 몫으로 돌아가며, 그 선택에 따른 책임과 결과물도 개발자의 몫이라고 생각합니다.

profile
무언가를 개발한지 2년이 되어가는 중입니다 @KSASolution

0개의 댓글