Java 8中使用Lambda表达式的策略模式

策略模式是“ 设计模式:可重用对象的元素”书中的模式之一 。 本书所述的策略模式的意图是:

定义一系列算法,封装每个算法,并使它们可互换。 策略使算法独立于使用该算法的客户端而变化。

在本文中,我想给出一个或两个关于策略模式的示例,然后使用要在Java 8中引入的lambda表达式重写相同的示例。

策略模式:一个例子

考虑一个声明策略的接口:

interface Strategy{
  public void performTask();
}

考虑此策略的两种实现:

class LazyStratgey implements Strategy{

  @Override
  public void performTask() {
    System.out.println("Perform task a day before deadline!");
  }

}

class ActiveStratgey implements Strategy{

  @Override
  public void performTask() {
    System.out.println("Perform task now!");
  }

}

上面的策略是幼稚的,我将其简化以帮助读者快速掌握它。 让我们看看这些策略的实际效果:

public class StartegyPatternOldWay {

  public static void main(String[] args) {

    List<Strategy> strategies = 
        Arrays.asList(
          new LazyStratgey(), 
          new ActiveStratgey()
        );

    for(Strategy stg : strategies){
      stg.performTask();
    }
  }
}

上面的输出是:

Perform task a day before deadline!
Perform task now!

策略模式:Lambda表达式示例

让我们看一下使用Lambda表达式的相同示例。 为此,我们将保留策略接口,但是我们不必创建该接口的其他实现,而是使用lambda表达式创建该策略的不同实现。 下面的代码展示了它的实际作用:

import java.util.Arrays;
import java.util.List;

public class StrategyPatternOnSteroids {
  public static void main(String[] args) {

    System.out.println("Strategy pattern on Steroids");

    List<Strategy> strategies = 
      Arrays.asList(
        () -> {System.out.println("Perform task a day before deadline!");},
        () -> {System.out.println("Perform task now!");}
      );

    strategies.forEach((elem) -> elem.performTask());
  }

}

上面的输出是:

Strategy pattern on Steroids
Perform task a day before deadline!
Perform task now!

在使用lambda表达式的示例中,我们避免将类声明用于不同的策略实现,而是使用了lambda表达式。

策略模式:另一个例子

此示例的灵感来自Neal Ford在IBM Developer上的文章: Functional Design Pattern-1 。 该示例的想法完全相似,但Neal Ford使用Scala,而我使用Java进行了相同的修改,只是命名约定有所变化。

让我们看一下接口Computation,它除了声明带有两个参数的方法compute外,还声明了泛型T。

interface Computation<T> {

  public T compute(T n, T m);
}

我们可以有这样的计算的不同实现方式: IntSum -返回两个整数的总和IntDifference -返回两个整数和的差异IntProduct -返回两个整数的乘积。

class IntSum implements Computation<Integer> {

  @Override
  public Integer compute(Integer n, Integer m) {
    return n + m;
  }

}

class IntProduct implements Computation<Integer> {

  @Override
  public Integer compute(Integer n, Integer m) {
    return n * m;
  }
}

class IntDifference implements Computation<Integer> {

  @Override
  public Integer compute(Integer n, Integer m) {
    return n - m;
  }
}

现在,让我们在下面的代码中查看这些策略的实际作用:

public class AnotherStrategyPattern {

  public static void main(String[] args) {

    List<Computation> computations = 
        Arrays.asList(
          new IntSum(), 
          new IntDifference(), 
          new IntProduct()
        );

    for (Computation comp : computations) {
      System.out.println(comp.compute(10, 4));
    }
  }
}

上面的输出是:

14
6
40

策略模式:使用lambda表达式的另一个示例

现在,让我们看看使用Lambda表达式的相同示例。 同样,与前面的示例一样,我们不需要为策略的不同实现(即Computation接口)声明类,而是使用lambda表达式来实现相同的效果。 让我们看一个例子:

public class AnotherStrategyPatternWithLambdas {
  public static void main(String[] args) {

    List<Computation<Integer>> computations = 
          Arrays.asList(
              (n, m)-> { return n+m; },
              (n, m)-> { return n*m; },
              (n, m)-> { return n-m; }
          );
    computations.forEach((comp) -> System.out.println(comp.compute(10, 4)));
  }
}

上面的输出是:

14
6
40

从以上示例中,我们可以看到使用Lambda表达式将有助于减少大量样板代码,以实现更简洁的代码。 通过实践,您可以习惯于阅读lambda表达式。


翻译自: https://www.javacodegeeks.com/2013/07/strategy-pattern-using-lambda-expressions-in-java-8.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值