策略模式是“ 设计模式:可重用对象的元素”书中的模式之一 。 本书所述的策略模式的意图是:
定义一系列算法,封装每个算法,并使它们可互换。 策略使算法独立于使用该算法的客户端而变化。
在本文中,我想给出一个或两个关于策略模式的示例,然后使用要在Java 8中引入的lambda表达式重写相同的示例。
策略模式:一个例子
考虑一个声明策略的接口:
interface Strategy{public void performTask();
}
考虑此策略的两种实现:
class LazyStratgey implements Strategy{@Overridepublic void performTask() {System.out.println("Perform task a day before deadline!");}}class ActiveStratgey implements Strategy{@Overridepublic 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> {@Overridepublic Integer compute(Integer n, Integer m) {return n + m;}}class IntProduct implements Computation<Integer> {@Overridepublic Integer compute(Integer n, Integer m) {return n * m;}
}class IntDifference implements Computation<Integer> {@Overridepublic 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