编程语言
首页 > 编程语言> > 深入浅出聊聊Java函数式编程思想

深入浅出聊聊Java函数式编程思想

作者:互联网

引言

一直以来,Java都被认为是一种面向对象的编程语言,“万事万物皆对象”的思想已经深入人心。但随着Java8的发布,一切看起来似乎有些改变。Lambda表达式和Stream的引入,让Java焕发了新的活力,它允许人们可以用函数式编程思维思考问题。本文主要介绍了函数式编程思想在Java中的应用。

指令式还是声明式?

先看一段代码:计算商品价格的最大值。 我们一般会这样实现:

int max = 0;
for(int price : prices) {
    if (max < price) {
        max = price;
    }
}

这就是典型的“指令式”(imperative)写法。它利用计算机的指令或者语法,告诉计算机一步步要做什么。 针对同样的功能,再看看另一种写法:

int max = prices.stream().reduce(0, Math::max);

如果熟悉软件设计原则的读者会发现,这正是“好莱坞原则”的使用,Tell,Don’t Ask!

用函数式思想实现设计模式

在GoF的经典著作《设计模式》一书中,详细介绍了23种常见的设计模式。细心的读者可能会发现,书名下面还有一行小字:可复用面向对象软件的基础。也就是说它是用面向对象思想实现的。这么多年过去了,对设计模式的争论一直在进行,但这已不再重要,今天让我们以函数式编程的角度重新审视设计模式。

命令模式

命令模式一般会对命令进行封装,对外提供接口供使用者调用。 先看一个例子:扫地机器人可以执行直行、左转、右转等指令操作。 先定义指令接口和实现类:

// 命令接口
public interface Command {
    void execute();
}
// 前进命令实现
public class forward implements Command {
    public void execute() {
        System.out.println("go forward");
    }
}
// 右转命令实现
public class Right implements Command {
    @Override
    public void execute() {
        System.out.println("go right");
    }
}

下面实现机器人:

public class Robot {
    public static void move(Command... commands) {
        for (Command command : commands) {
            command.execute();
        }
    }
    public static void main(String[] args) {
        Robot.move(new Forward(), new Right());
    }
}

虽然功能实现了,但有一个问题就是:创建的类太多!

我们看看函数式编程怎么实现?

因为Command接口中的execute()是一个无入参和无返回结果的方法,这让我们很自然的想起了Java内置的函数式接口Runnable,它也有一个同样签名的run()方法。虽然Runnable接口本来是用在多线程处理中的,但这里我们取巧的用在函数式编程中。

首先我们把Robot类的move()方法的入参替换为Runnable接口:

public static void flexibleMove(Runnable... commands) {
	Stream.of(commands).forEach(Runnable::run);
}
复制代码

这样一来,我们只需要在类方法中实现命令就可以了。

public static void forward() {
	System.out.println("go forward");
}
public static void right() {
	System.out.println("go right");
}

调用就变成了:

Robot.flexibleMove(Robot::forward, Robot::right);

这种实现减少了很多命令实现类,把焦点更多放在业务逻辑上。

标签:Java,系统,操作系统,硬件配置,安装,电子计算机,存储器,主机
来源: