策略模式是“ 设计模式:可重用对象的元素”书中的模式之一 。 本书所述的策略模式的意图是:
定义一系列算法,封装每个算法,并使它们可互换。 策略使算法独立于使用该算法的客户端而变化。
在本文中,我想给出一个或两个关于策略模式的示例,然后使用要在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