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

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

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

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,没有一大堆类。实际应用就这么简单就可以使用了。简直没有比这跟简单的策略模式案例了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 设计模式概述 在学习面向对象七大设计原则时需要注意以下几点:a) 高内聚、低耦合和单一职能的“冲突”实际上,这两者...
    彦帧阅读 3,798评论 0 14
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,001评论 19 139
  • 设计模式汇总 一、基础知识 1. 设计模式概述 定义:设计模式(Design Pattern)是一套被反复使用、多...
    MinoyJet阅读 3,984评论 1 15
  • 哭殷遥 唐代 王维 人生能几何,毕竟归无形。 念君等为死,万事伤人情。 慈母未及葬,一女才十龄。 泱漭寒郊外,萧...
    境心园阅读 709评论 1 0
  • 情绪:欣喜 情绪来源: 大家都知道我是做大学生创业孵化器的,最近又接了很多单,但现在同学们都放假了,我就试探性的在...
    顽伴高振裕阅读 127评论 2 1