美文网首页设计模式设计模式设计模式
设计模式:第一篇--策略模式

设计模式:第一篇--策略模式

作者: Jorgezhong | 来源:发表于2018-09-14 15:24 被阅读126次

    策略模式:定义了算法族,分别封装起来,让算法族下的算法之间可以被替换。策略模式将算法独立于使用算法的客户之外。

    其实我们已经学会了策略模式了。在上一篇最后使用的其实就是策略模式。回去翻一下会发现,我们把鸭子的行为(算法族)封装起来,给行为具体实现(算法)。组合行为(算法族)到鸭子上实现动态可以动态改变行为(算法)。这不就是策略模式吗。本篇我们找个实际应用到的例子。

    JDK8的java.util.function包下提供了一系列算法族。其实接口Supplier、Predicate、Consumer、Function这些我们在学习jdk8特性的时候会接触到。因为jdk8最大一个设计就是函数式编程了。其实其中就大量用到了策略模式。只不过不同的是,我们之前是提前将实现写好放到一个类里面,这里是直接匿名实现。当成参数传递下去。这一系列接口出来之后,感觉没有比这些更简单的策略模式实例了。简直一目了然。

    最简单的例子:Consumer

    @FunctionalInterface
    public interface Consumer<T> {
    
        /**
         * Performs this operation on the given argument.
         *
         * @param t the input argument
         */
        void accept(T t);
    
        /**
         * Returns a composed {@code Consumer} that performs, in sequence, this
         * operation followed by the {@code after} operation. If performing either
         * operation throws an exception, it is relayed to the caller of the
         * composed operation.  If performing this operation throws an exception,
         * the {@code after} operation will not be performed.
         *
         * @param after the operation to perform after this operation
         * @return a composed {@code Consumer} that performs in sequence this
         * operation followed by the {@code after} operation
         * @throws NullPointerException if {@code after} is null
         */
        default Consumer<T> andThen(Consumer<? super T> after) {
            Objects.requireNonNull(after);
            return (T t) -> { accept(t); after.accept(t); };
        }
    }
    
    

    我们看到Consumer接口写了两个方法。一个是accept另一个是andThen。其中andThen已经提供了默认实现。而accept则没有。因此该接口的子类是都要要求实现accept方法的。该接口定义了一个Consumer算法族。接收一个T类型的参数t,并实现自定义逻辑。

    最简单明了的使用

    public class DemoTest {
    
        @Test
        public void test() {
    
            //定义五个策略:每个策略实现一个算法
            Consumer<String> strategy1 = o -> System.out.println("算法1:" + o);
            Consumer<String> strategy2 = o -> System.out.println("算法2:" + o);
            Consumer<String> strategy3 = o -> System.out.println("算法3:" + o);
            Consumer<String> strategy4 = o -> System.out.println("算法4:" + o);
            Consumer<String> strategy5 = o -> System.out.println("算法5:" + o);
    
            //执行算法
            strategy1.accept("参数1");
            strategy2.accept("参数2");
            strategy3.accept("参数3");
            strategy4.accept("参数4");
            strategy5.accept("参数5");
            
        }
        
    }
    
    

    可以说代码是很清晰了,定义了五个策略实现每个策略的算法,然后执行。如果没有这么写过代码没关系。看下面这段。

    public class DemoTest {
    
        @Test
        public void test() {
            
            strategy(t -> System.out.println("算法" + t + ":参数" + t),"1");
            strategy(t -> System.out.println("算法" + t + ":参数" + t),"2");
            strategy(t -> System.out.println("算法" + t + ":参数" + t),"3");
            strategy(t -> System.out.println("算法" + t + ":参数" + t),"4");
            strategy(t -> System.out.println("算法" + t + ":参数" + t),"5");
    
        }
    
        /**
         * 策略
         * @param consumer
         * @param t
         * @param <T>
         */
        public <T> void strategy(Consumer<T> consumer,T t) {
            consumer.accept(t);
        }
    
    }
    

    定义了一个参数类型为Consumer算法族接口,在待用的的时候传入实现(算法),并传入需要的参数。这就形成了一个策略。然后该接口调用方法accept去执行策略。整个策略模式的核心就是将动态实现算法族的算法,抽象的不是参数,而是实现和算法。是不是很简单。没有复杂的UML,没有一大堆类。实际应用就这么简单就可以使用了。简直没有比这跟简单的策略模式案例了。

    相关文章

      网友评论

        本文标题:设计模式:第一篇--策略模式

        本文链接:https://www.haomeiwen.com/subject/zpwwgftx.html