Command模式是对象式很容易转换到函数式的一个模式,让我们看一个简单的例子来说明它是如何工作的。首先,有必要定义一个建模命令的接口:
interface Command { |
提供此Command接口的不同实现。例如,假设我们需要不同的命令来处理消息 - 您可以使用一个命令来记录消息:
public class Logger implements Command { |
将消息保存在文件中是另外一个命令实现:
public class FileSaver implements Command { |
电子邮件发送:
public class Mailer implements Command { |
一个可以执行以多个命令的对象:
public class Executor { |
最后可以将我们想要运行的命令添加到List中并通过Executor执行它们:
List<Command> tasks = new ArrayList<>(); |
Gang of Four书中建议我们将函数(要执行的动作)包装到对象(执行这些动作的命令)中,然而,这种间接级别除了允许我们将函数适合于严格面向对象的编程风格。但是,随着Java 8中lambda的引入,现在可以无缝地混合函数和面向对象的范例,我们可以以更紧凑的方式重新思考前一个例子。
首先,请注意我们不需要定义Command接口:Runnable,它存在于Java的第一个版本中,它有一个抽象方法,具有与Command 1相同的签名。前3命令实现可以通过3个函数以更简洁的方式替换,在Java 8中可以使用3个静态方法实现:
public static void log(String message) { |
使用函数式思维重新思考命令实现带来了显着提高代码信号/噪声比的好处,其中信号是函数体,而噪声是用于表示该函数的所有附加代码作为方法一个东西。甚至Executor类也可以用单行静态方法替换,将List of Runnables作为参数:
public static void execute(List<Runnable> tasks ) { |
我们的函数可以添加到List中,并像以前一样执行。
List<Runnable> tasks = new ArrayList<>(); |
Java编译器自动转换不带参数的lambda,并调用void静态方法,作为Runnable接口的匿名实现,从而让Runnables类型的集合Collection中容纳它们,而之前是需要实现Command接口的。