Justin의 개발 로그

전통적인 디자인패턴(GoF)에서 전략패턴

public class OriginalStrategyPattern {

	//인터페이스 선언
    public interface ValidationStrategy {
        boolean execute(String s);
    }

	//클래스 구현 - 소문자 검증
    private class IsAllLowerCase implements ValidationStrategy {
        @Override
        public boolean execute(String s) {
            return s.matches("[a-z]+");
        }
    }

	//클래스 구현 - 숫자 검증
    private class IsNumeric implements ValidationStrategy {

        @Override
        public boolean execute(String s) {
            return s.matches("\\d+");
        }
    }

	//주입을 통해 SOLID 
    private class Validator {
        private final ValidationStrategy strategy;

        private Validator(final ValidationStrategy strategy) {
            this.strategy = strategy;
        }

        public boolean validate(String s) {
            return strategy.execute(s);
        }
    }

	//테스트
    @Test
    void numericValidateTest() {
        Validator numericValidator = new Validator(new IsNumeric());
        boolean isNumeric = numericValidator.validate("1245");

        Assertions.assertTrue(isNumeric);
    }

    @Test
    void lowerCaseValidateTest() {
        Validator lowerCaseValidator = new Validator(new IsAllLowerCase());
        boolean isLowerCase = lowerCaseValidator.validate("abcdef");

        Assertions.assertTrue(isLowerCase);
    }

}

 

람다를 활용해서 전략 패턴을 간단히 구현

public class LambdaStrategy {
    // 인터페이스 정의 - Predicate<T>를 사용해되 되나, 메서드명이 validate()가 더 직관적이니까
    @FunctionalInterface
    public interface Validator<T> {
        boolean validate(T t);
    }

    // 메서드 참조 생성
    Validator<String> lowerCaseValidator = (String s) -> s.matches("[a-z]+");
    Validator<String> numericValidator = (String s) -> s.matches("\\d+");

    //테스트
    @Test
    void lowerCaseTest() {
        boolean isLowerCase = lowerCaseValidator.validate("abcde");
        Assertions.assertTrue(isLowerCase);
    }

    @Test
    void numericTest() {
        boolean isNumeric = numericValidator.validate("12345");
        Assertions.assertTrue(isNumeric);
    }
}

 

테스트를 제외하고 Predicate<T>를 사용하면 구현 코드는 2줄

   // 메서드 참조 생성
    Predicate<String> lowerCaseValidator2 = (String s) -> s.matches("[a-z]+");
    Predicate<String> numericValidator2 = (String s) -> s.matches("\\d+");

    @Test
    void lowerCaseTest2() {
        boolean isLowerCase = lowerCaseValidator2.test("abcde");
        Assertions.assertTrue(isLowerCase);
    }

    @Test
    void numericTest2() {
        boolean isNumeric = numericValidator2.test("12345");
        Assertions.assertTrue(isNumeric);
    }
  • 대신 validate() 메서드 대신에 Predicate<T>의 test() 메서드 사용해야 함
profile

Justin의 개발 로그

@라이프노트

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!