전략 패턴(Strategy Pattern)

최재용·2021년 6월 10일
0

우아콘2020에서 프론트 서버의 구조를 보던중에 문득 DIP(의존성 역전 원칙)와 관련있는 전략 패턴이 등장하여 다시한번 기억하고자 이 글을 작성합니다.

흔히 우리가 많은 곳에서 쓰고 있지만 디자인 패턴 측면(좀더 이론적인??)에서 접근해보고자 합니다.

추가로 Spring boot 예제도 구현해보겠습니다.

전략 패턴

어느 한 객체가 특정 컴포넌트에 의존하게 되면 후에 해당 객체에 기능이 추가되고 변하게 되었을 때 유연한 대처(소스코드 변경 및 컴포넌트 변경 대처 등)를 하기가 어렵습니다. 다음은 특정 컴포넌트 A에 의존적인 객체(Context)를 나타냅니다.

이러한 문제를 해결하기 위해 다음과 같이 특정 컴포넌트들의 의존성을 역전시킨 전략패턴을 사용할 수 있습니다.

위 그림과 같이 전략 패턴은 추상화 계층을 사용하여 특정 컴포넌트에 의존성을 가지지 않고 역으로 컴포넌트들이 특정 전략을 의존하게 함으로써 컴포넌트를 사용하는 입장에서 여러 컴포넌트들을 선택하여 사용할 수 있게 하는 패턴입니다.

이러한 전략 패턴의 장점은 새로운 기능의 컴포넌트를 추가하려고 했을 때, 기존 코드를 고치지 않고 새로운 컴포넌트를 만들면 되는 장점이 있습니다.

또한 해당 추상화 계층을 구현하는 실제 컴포넌트들은 일관된 함수를 구현하고 있기 때문에 다른 컴포넌트 구현체를 사용하더라도 컴포넌트를 사용하는 입장에서 소스코드를 크게 바꿀일이 없습니다.

간단한 전략 패턴 구현

Spring boot 예제를 통하여 전략 패턴을 간단하게 구현해 보겠습니다.

에제 코드는 문자열에 특정 prefix를 더하여 반환함수를 가지는 Prefixer 인터페이스와 구현체들입니다.

Prefixer.java

package com.example.strategypattern;

public interface Prefixer {

    String addPrefix(String str);
}

APrefixer.java

package com.example.strategypattern;

import org.springframework.stereotype.Component;

@Component
class APrefixer implements Prefixer{
    private static final String PREFIX = "A_";

    public String addPrefix(String str) { 
    	return PREFIX + str; 
    }
}

BPrefixer.java

package com.example.strategypattern;

import org.springframework.stereotype.Component;

@Component
class BPrefixer implements Prefixer{
    private static final String PREFIX = "B_";

    public String addPrefix(String str) { 
    	return PREFIX + str; 
    }
}

테스트 코드 예제

package com.example.strategypattern;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest
class StrategyPatternApplicationTests {

    @Autowired
    private BPrefixer bPrefixer;

    @Autowired
    private APrefixer aPrefixer;

    @Test
    public void testAPrefix() {
        String result = aPrefixer.addPrefix("TEST");

        assertEquals("A_TEST", result);
    }

    @Test
    public void testBPrefix() {
        String result = bPrefixer.addPrefix("TEST");

        assertEquals("B_TEST", result);
    }
}

결론

전략 패턴은 실제로 개발을 하면서 디자인 패턴이라는 것을 알지 못해도 많이 사용하는 패턴입니다.

그냥 쓰던 방식으로만 아는 것이 아니라 어떤 장점이 있고 단점이 있는지 여러가지 측면에서 다른 패턴들과 비교해보면 프로그램을 설계할 때 조금 더 도움이 되는 것 같습니다.

참고

우아콘2020에서 보았던 관련 패턴 영상 캡처입니다.

profile
개발 로그

0개의 댓글