본문 바로가기

개인공부/디자인패턴

전략 패턴

반응형

https://redbinalgorithm.tistory.com/720

 

템플릿 메서드 패턴

기본 로직 템플릿 메서드 패턴은 여러 반복되는 메서드들을 줄여 줄 수 있는 패턴이다. /// 고정로직 /// /// 비즈니스 로직 /// /// 고정로직 /// 다음과 같이 고정로직이 반복되고 비즈니스 로직만

redbinalgorithm.tistory.com

 

포스팅을 시작하며 이전 템플릿 메서드 패턴에 대해서 공부 했다.

 

전략패턴도 고정된 로직과 바뀌는 비즈니스 로직을 어떻게하면 좋은 유지보스로 적용할 수 잇을까? 라는 생각으로 나오게 된 패턴이다.

 

먼저! , 이전의 템플릿 메서드 패턴의 클라이언트 구조를 살펴보자.

    @Test
    void templateMethodV() {
        AbstractTemplateT template1 = new SubClassLogic1();
        template1.execute();

        AbstractTemplateT template2 = new SubClassLogic2();
        template2.execute();
    }

다음과 같은 코드이다. 추상 메서드는 고정된 템플릿을 생성하고 추상메서드의 call()을 서브클래스가 구현하는 방법으로 고정된 로직과 비즈니스 로직을 분리하는 방법을 사용한다.

 

구글에서 전략 패턴의 이미지를 검색해보자!

 

 

앞선 템플릿 메서드 패턴이 추상 클래스를 사용하였다면 전략패턴은 Strategy라는 인터페이스와 그것을 구현하는 여러 전략들이 존재하고

Context를 통해서 호출하게 된다.

 

코드로 적용 시켜보자.

 

먼저 전략에 들어가는 Interface Strategy

public interface Strategy {
	void call();
}

 

이것을 구현하는 Strategy들의 구현체를 구현한다.

 

public class StrategyLogic1 implements Strategy{
    @Override
    public void call() {
        log.info("비즈니스 로직 1");
    }
}

public class StrategyLogic2 implements Strategy{
    @Override
    public void call() {
        log.info("비즈니스 로직2");
    }
}

 

마지막으로는 Context를 통해서 전략을 선택하고 사용하는 코드를 구성한다.

 

public class Context{
	private Strategy strategy;
    
    public ContextV1(Strategy strategy) { this.strategy = strategy; }
    
    public void execute() {
    	// 고정 로직
    	long start = System.currentTimeMillis();
        
        // 비즈니스 로직
        strategy.call();
        
        // 고정 로직
        long end = System.currentTimeMillis();
        long result = end - start;
        System.out.println("result = " + result);
    }
}

해당 콘텍스트에 전략을 맞추어가면서 로직을 구성한다.

    void strategyV1() {
        StrategyLogic1 strategyLogic1 = new StrategyLogic1();
        ContextV1 context1 = new ContextV1(strategyLogic1);
        context1.execute();

        StrategyLogic2 strategyLogic2 = new StrategyLogic2();
        ContextV1 context2 = new ContextV1(strategyLogic2);
        context2.execute();
    }

 

 

전략 패턴과 템플릿 메서드 패턴은 목적은 똑같다. 하지만 전략 패턴은 전략이라는 서로 다른 비즈니스 로직을 선택하여 Context라는 함수에서 고정로직을 고정하고 전략을 바꿔가면서 호출한다는 점에서 차이점을 알 수 있다.

 

좀 더 고도화

 

이전에서 전략패턴은 Context안에서 Starategy를 가지고 있고 해당전략을 필요한 전략의 로직을 class로 만들어야 한다는 불편한것이 있다. 하지만 Java에는 인터페이스 함수를 클래스로 구성하지 않으면 @Override를 통해서 직접 구현할 수 있고 더 나아가 

 

lamda 를 사용해서 좀더 간결하게 만들 수 있다. lamda는 java에서는 인터페이스의 하나의 함수를 구현하고 있는 인터페이스를 간결하게 할 수 있는 java 8 버전부터 제공되는 기능 중에 하나 이다.

 

    @Test
    void strategyV2() {
        ContextV2 context = new ContextV2();
        context.execute(new Strategy() {
            @Override
            public void call() {
                log.info("비즈니스 로직 1 실행");
            }
        });
        context.execute(new Strategy() {
            @Override
            public void call() {
                log.info("비즈니스 로직 2 실행");
            }
        });
    }

아래를 보자 아까는 call을 불러오는 비즈니스 로직 클래스 자체를 구현하고 해당 로직에 넣어주어야 했다면 아래와같이 @Override를 해주어서 전략에 해당하는 비즈니스 로직을 갈아 끼울 수 있다.

 

여기서 람다식을 이용하게된다면 다음과 같이 전략패턴을 깔끔하게 사용할 수 있다.

 

    @Test
    void strategyV3() {
        ContextV2 context = new ContextV2();
        context.execute(() -> log.info("비즈니스 로직 1 실행"));
        context.execute(() -> log.info("비즈니스 로직 2 실행"));
    }
반응형