内容简介:Command模式是对象式很容易转换到函数式的一个模式,让我们看一个简单的例子来说明它是如何工作的。首先,有必要定义一个建模命令的接口:提供此Command接口的不同实现。例如,假设我们需要不同的命令来处理消息 - 您可以使用一个命令来记录消息:将消息保存在文件中是另外一个命令实现:
Command模式是对象式很容易转换到函数式的一个模式,让我们看一个简单的例子来说明它是如何工作的。首先,有必要定义一个建模命令的接口:
<b>interface</b> Command {
<b>void</b> run();
}
提供此Command接口的不同实现。例如,假设我们需要不同的命令来处理消息 - 您可以使用一个命令来记录消息:
<b>public</b> <b>class</b> Logger implements Command {
<b>public</b> <b>final</b> String message;
<b>public</b> Logger( String message ) {
<b>this</b>.message = message;
}
@Override
<b>public</b> <b>void</b> run() {
System.out.println(<font>"Logging: "</font><font> + message);
}
}
</font>
将消息保存在文件中是另外一个命令实现:
<b>public</b> <b>class</b> FileSaver implements Command {
<b>public</b> <b>final</b> String message;
<b>public</b> FileSaver( String message ) {
<b>this</b>.message = message;
}
@Override
<b>public</b> <b>void</b> run() {
System.out.println(<font>"Saving: "</font><font> + message);
}
}
</font>
电子邮件发送:
<b>public</b> <b>class</b> Mailer implements Command {
<b>public</b> <b>final</b> String message;
<b>public</b> Mailer( String message ) {
<b>this</b>.message = message;
}
@Override
<b>public</b> <b>void</b> run() {
System.out.println(<font>"Sending: "</font><font> + message);
}
}
</font>
一个可以执行以多个命令的对象:
<b>public</b> <b>class</b> Executor {
<b>public</b> <b>void</b> execute(List<Command> tasks) {
<b>for</b> (Command task : tasks) {
task.run();
}
}
}
最后可以将我们想要运行的命令添加到List中并通过Executor执行它们:
List<Command> tasks = <b>new</b> ArrayList<>(); tasks.add(<b>new</b> Logger( <font>"Hi"</font><font> )); tasks.add(<b>new</b> FileSaver( </font><font>"Cheers"</font><font> )); tasks.add(<b>new</b> Mailer( </font><font>"Bye"</font><font> )); <b>new</b> Executor().execute( tasks ); </font>
Gang of Four书中建议我们将函数(要执行的动作)包装到对象(执行这些动作的命令)中,然而,这种间接级别除了允许我们将函数适合于严格面向对象的编程风格。但是,随着 Java 8中lambda的引入,现在可以无缝地混合函数和面向对象的范例,我们可以以更紧凑的方式重新思考前一个例子。
首先,请注意我们不需要定义Command接口:Runnable,它存在于Java的第一个版本中,它有一个抽象方法,具有与Command 1相同的签名。前3命令实现可以通过3个函数以更简洁的方式替换,在Java 8中可以使用3个静态方法实现:
<b>public</b> <b>static</b> <b>void</b> log(String message) {
System.out.println(<font>"Logging: "</font><font> + message);
}
<b>public</b> <b>static</b> <b>void</b> save(String message) {
System.out.println(</font><font>"Saving: "</font><font> + message);
}
<b>public</b> <b>static</b> <b>void</b> send(String message) {
System.out.println(</font><font>"Sending: "</font><font> + message);
}
</font>
使用函数式思维重新思考命令实现带来了显着提高代码信号/噪声比的好处,其中信号是函数体,而噪声是用于表示该函数的所有附加代码作为方法一个东西。甚至Executor类也可以用单行静态方法替换,将List of Runnables作为参数:
<b>public</b> <b>static</b> <b>void</b> execute(List<Runnable> tasks ) {
tasks.forEach( Runnable::run );
}
我们的函数可以添加到List中,并像以前一样执行。
List<Runnable> tasks = <b>new</b> ArrayList<>(); tasks.add(() -> log(<font>"Hi"</font><font>)); tasks.add(() -> save(</font><font>"Cheers"</font><font>)); tasks.add(() -> send(</font><font>"Bye"</font><font>)); execute( tasks ); </font>
Java编译器自动转换不带参数的lambda,并调用void静态方法,作为Runnable接口的匿名实现,从而让Runnables类型的集合Collection中容纳它们,而之前是需要实现Command接口的。
以上所述就是小编给大家介绍的《使用函数式实现命令模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- PHP中exec()函数执行系统命令失败
- 关于如何处理面向对象、函数式、命令式、声明式编程
- JavaScript中的函数与命令模式,Java也有参考价值
- CVE-2018-19518:PHP imap_open函数任意命令执行漏洞复现
- 【巨杉数据库Sequoiadb】【咨询】【内置SQL】执行exec命令查询substr函数时报错-195
- Flask 偏函数、g对象、flask-session、数据库连接池、信号、自制命令、flask-admin
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
创投之巅——中国创投精彩案例
投资界网站 / 人民邮电出版社 / 2018-11 / 69.00
中国的科技产业发展,与创投行业密不可分。在过去的几十年间,资本与科技的结合,缔造了众多创业“神话”。回顾这些科技巨头背后的资本路径,可以给如今的国内创业者很多有益的启发。 本书从风险投资回报率、投资周期、利润水平、未来趋势等多个维度,筛选出了我国过去几十年中最具代表性的创业投资案例,对其投资过程和企业成长过程进行复盘和解读,使读者可以清晰地看到优秀创业公司的价值与卓越投资人的投资逻辑。一起来看看 《创投之巅——中国创投精彩案例》 这本书的介绍吧!