Lambda 표현식으로 정책 간소화

24317 단어 designpatterns
전략 설계 모델은 소프트웨어 개발 분야에서 가장 광범위하게 사용되는 모델 중의 하나다.본고에서 우리는 전략 디자인 모델을 배울 것이다. 언제 사용하고, 언제 사용하지 않을 것이다. 우리는 어떻게 이 모델을 이용하여 우리의 디자인을 더욱 유연하게 할 것인가?우리는 람다와 람다가 없는 상황에서 어떻게 그것을 실현하는지 예시를 볼 것이다.

2. 전략 설계 모델


2.1 정의


위키백과를 검색하는 시간을 절약하기 위해 다음과 같이 정의합니다.

The strategy pattern (also known as the policy pattern) is a behavioral software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use. Strategy lets the algorithm vary independently from clients that use it.


전략 모델의 사상은 일련의 알고리즘을 정의하여 변화를 단독 클래스에 봉인하고 그 대상을 상하문에서 교환할 수 있도록 하는 것이다.여기서'변화'는 시간의 추이에 따라 끊임없이 변화하는 수요에 따라 변화할 수 있다는 것을 가리킨다.

2.2 UML 그림


Context류는 어떠한 전략(알고리즘)도 실현하지 못한다.반대로, 그것은 Strategy 인터페이스에 대한 인용을 보류했다.Context류는 이런 알고리즘의 실현에 무관심하다.그것이 알고 있는 것은 이 알고리즘을 실행할 수 있다는 것이다.StrategyImpl1StrategyImpl2실현Strategy인터페이스, 표시, 실현과 봉인 알고리즘.

2.3 정책 모드 사용/회피 시기


원하는 경우:
  • 대상 내에서 서로 다른 알고리즘을 사용하고 실행할 때 한 알고리즘에서 다른 알고리즘으로 전환할 수 있다.
  • 고객에게 알고리즘의 실현과 무관한 세부 사항을 숨긴다.의존 주입 메커니즘을 사용하여 실행할 때 클라이언트에 주입할 수 있습니다.
  • 한 줄의 방법으로 대량의 조건을 호출하여 교체한다.주의, 위탁은 이곳에서 중요한 역할을 한다. 왜냐하면 단행 방법은 운행할 때 인용 유형(Dynamic dispatch!)에 따라 적절하게 호출되기 때문이다.
  • 합성으로 계승 대체
  • 당신의 알고리즘이 매우 적게 바뀔 때, 전략 모드를 사용하지 말고, 모드에 첨부된 새로운 종류와 인터페이스로 과도하게 프로그램을 설계할 필요가 없다

    2.4 고전 전략


    이 예에서 자바에서 고전적인 전략 모델을 실현하는 방법을 보여 드리겠습니다.이 예는 여러 가지 알고리즘(또는 정책)을 사용하여 목록을 정렬하고 검색하는 가상 프로그램을 모의했다.다음은 우리 프레젠테이션의 분류도입니다.

    주의, Client류는 Context와 일부 전략적 실현에 의존한다. (나는 우리를 그리지 않았다. 왜냐하면 우리는 여기서 스파게티를 먹고 싶지 않기 때문이다.)이것은 우리가 보여준 실현 (가상):
    import java.util.List;
    
    interface SortStrategy {
        void sort(List<String> list);
    }
    
    class QuickSortStrategyImpl implements SortStrategy {
    
        @Override
        public void sort(List<String> list) {
            System.out.println("List sorted using Quick sort implementation");
        }
    }
    
    class BubbleSortStrategyImpl implements SortStrategy {
    
        @Override
        public void sort(List<String> list) {
            System.out.println("List sorted using Bubble sort implementation");
        }
    }
    
    interface SearchStrategy {
        String search(String s);
    }
    
    class BinarySearchStrategyImpl implements SearchStrategy {
        @Override
        public String search(String s) {
            System.out.println("list is binary searched");
            return null;
        }
    }
    
    class LinearSearchStrategyImpl implements SearchStrategy {
    
        @Override
        public String search(String s) {
            System.out.println("list is linearly searched");
            return null;
        }
    }
    
    class Context {
        private SortStrategy sortStrategy;
    
        private SearchStrategy searchStrategy;
    
        public Context(SortStrategy sortStrategy, SearchStrategy searchStrategy) {
            this.sortStrategy = sortStrategy;
            this.searchStrategy = searchStrategy;
        }
    
        public void setSortStrategy(SortStrategy sortStrategy) {
            this.sortStrategy = sortStrategy;
        }
    
        public void setSearchStrategy(SearchStrategy searchStrategy) {
            this.searchStrategy = searchStrategy;
        }
    
        public void sort(List<String> list) {
            sortStrategy.sort(list);
        }
    
        public String search(String s) {
            // perform search
            return searchStrategy.search(s);
        }
    }
    
    class Client {
        public static void main(String[] args) {
            List<String> list = List.of("b", "a", "c");
            Context context = new Context(new BubbleSortStrategyImpl(), new BinarySearchStrategyImpl());
            context.sort(list);
            String searchedElement1 = context.search("b");
    
            System.out.println("---------------");
    
            context.setSortStrategy(new QuickSortStrategyImpl());
            context.setSearchStrategy(new LinearSearchStrategyImpl());
            context.sort(list);
            String searchedElement2 = context.search("a");
        }
    }
    
    출력:
    List sorted using Bubble sort implementation
    list is binary searched
    ---------------
    List sorted using Quick sort implementation
    list is linearly searched
    
    클래스Context는 정책을 설명하는 인터페이스SortStrategySearchStrategy에만 의존합니다.그것은 이 인터페이스들의 실현에 무관심하다.BubbleSortStrategyImplBinarySearchStrategyImpl는 각각 이러한 인터페이스를 실현하는 유형이다.앞에서 말한 바와 같이, 그들은 전략 (알고리즘) 을 실현하고 봉인했다.
    예를 들어 75줄에서 클라이언트는 이러한 실현을 상하문 클래스에 주입한다.그래서 우리가 상하문을 호출할 때정렬 (목록) 및 컨텍스트.검색 ("b") 이 실행될 때, 상하문은 어떤 실현을 실행해야 하는지 알 수 있습니다.
    클래스 상하문은 setter를 공개하여 클라이언트가 실행할 때 상하문과 관련된 정책을 바꾸도록 합니다. (기억하십시오: 정책은 알고리즘이 클라이언트를 사용하는 것과 독립적으로 변하도록 허용합니다.)
    만약 우리가 다른 정렬이나 검색 정책을 추가할 필요가 있다면, 우리는 적당한 정책 인터페이스를 통해 그것을 추가할 수 있으며, 기존의 코드를 변경할 필요가 없다.전략 설계 모델이 개방/폐쇄 원칙을 촉진시켰다는 것을 알 수 있습니다.

    3. Lambda 표현식 및 정책 모드


    3.1 개요


    Lambda 표현식은 자바의 세계를 바꾸었다. 우리는 대량의 의식 코드를 작성하는 것을 피하기 위해 Lambda 표현식을 효과적으로 사용할 수 있다.
    전략 설계 모델에 대해 말하자면, 우리는 클래스의 차원 구조를 만들 필요가 없다.반대로 우리는 인터페이스의 전략을 람다 표현식으로 상하문에 직접 전달할 수 있다.

    3.2 단순화 전략


    위의 코드는 매우 지루하고 간단한 알고리즘에 있어서 매우 많은 예절이 있다.우리는 lambda 표현식을 이용하여 코드의 지루성을 줄일 수 있다.lambda를 사용하면 우리는 함수 대상 그룹 내에서 서로 다른 버전의 알고리즘을 실현할 수 있으며, 추가 클래스로 코드를 팽창시키지 않습니다.
    이 프레젠테이션에서, 우리는 사용자 정의 인터페이스와 클래스를 만드는 것을 피하기 위해lambda 표현식을 사용하기 위해 코드를 재구성할 것입니다.이것은 재구성 구현(가상) 코드입니다.
    class Context {
        private Consumer<List<String>> sortStrategy;
        private Function<List<String>, String> searchStrategy;
    
        void sort(List<String> list) {
            sortStrategy.accept(list);
        }
    
        public Context(Consumer<List<String>> sortStrategy, Function<List<String>, String> searchStrategy) {
            this.sortStrategy = sortStrategy;
            this.searchStrategy = searchStrategy;
        }
    
        public void setSortStrategy(Consumer<List<String>> sortStrategy) {
            this.sortStrategy = sortStrategy;
        }
    
        public void setSearchStrategy(Function<List<String>, String> searchStrategy) {
            this.searchStrategy = searchStrategy;
        }
    
        public String search(List<String> list) {
            return searchStrategy.apply(list);
        }
    }
    
    class Client {
        public static void main(String[] args) {
            List<String> list = List.of("b", "a", "c");
            Consumer<List<String>> bubbleSort = l -> System.out.println("List sorted using Bubble sort implementation");
            Function<List<String>, String> binarySearch = list1 -> {
                System.out.println("list is binary searched");
                return null;
            };
            Context context = new Context(bubbleSort, binarySearch);
    
            context.sort(list);
            String searchedElement = context.search(list);
    
            System.out.println("-------------");
    
            Consumer<List<String>> quickSort = list1 -> System.out.println("List sorted using Quick sort implementation");
            Function<List<String>, String> linearSearch = l -> {
                System.out.println("list is linearly searched");
                return null;
            };
            context.setSortStrategy(quickSort);
            context.setSearchStrategy(linearSearch);
            context.sort(list);
            context.search(list);
        }
    }
    
    주의, 나는 어떤 인터페이스도 만들지 않았습니다. 왜냐하면 나는 java.util.function 패키지의 기능 인터페이스를 사용했기 때문입니다.
    출력은 이전과 같다.그러나 주의해야 할 것은 이 전략을 실현하기 위해 클래스와 인터페이스를 만들지 않았다는 것이다.나는 Context Consumer 인터페이스로 Function 클래스를 구성하고, 실행할 때 정책 행동을 변경하기 위해setter를 만들었다.
    클라이언트에서 나는 function object 류를 Context류에 전달할 것이다.

    4. 결론


    본고에서 우리는 전략 디자인 모델의 정의와 이를 어떻게 사용하여 디자인을 유연하게 하는지 이해했다.우리는 전략 모델의 고전적인 실현과 자바 8의 특성을 이용한 실현을 배웠다.다음 글에서는 더 많은 핵심 Java를 소개할 것입니다.기대해주세요!
    아래 댓글에서 당신의 생각을 알려주세요. 공유하는 것을 잊지 마세요!

    좋은 웹페이지 즐겨찾기