函数式编程是一种编程范式,在Java中可以使用Vavr和Project Reactor进行实践。 但在团队掌握函数式编程的基本技能后仍面临两大顽疾。
顽疾1 - null
null
在Java中是一个普遍的存在,经常被用于表示无效状态。有时我们会先检查变量是否为null
,然后再做正常的逻辑运算。有时我们也会在无法得到合理结果时返回null
。
在函数式编程中是不能出现null
的,因为使用它的函数不是纯函数。因此我们引入了Option
来替代null
。
我们无法在开发过程中完全避免null
的出现。Java语言本身, JVM或IDE都无法阻止我们使用null
。Java的第三方库也经常返回null
。
我们只能依靠团队的约定来避免null
的出现。在业务代码中我们可以约定不使用null
。而在业务代码的边界,我们可以在第一时间将null
替换为Option
,例如在调用第三方库时或在调用Java底层函数时进行替换。
null
的吸引力非常巨大,约定会被反复打破。因为在重载构造函数时给默认参数传入null
真的很方便,在处理函数参数时不判断一下null
实在是不放心,在调用三方库时替换null
真是太麻烦了。
顽疾2 - 多态
多态是面向对象编程的核心,它允许子类间有不同的行为。当我们想要增加一个新的行为时,会先在父类增加一个新的方法,然后再在各个子类实现该方法。这也就意味着每次增加新的行为都需要修改已有代码。
函数式编程中不能出现多态,因为它极易引起破窗效应,造成类中状态的改变,违反数据的不变性原则。
函数式编程可以在不改变已有代码的情况下,增加新的行为。当我们想要增加一个新的行为时,我们会新建一个函数,这个函数的入参类型是父类,函数内部会判断实例属于哪个子类然后执行相应的逻辑。
在不使用多态的情况下,函数式编程中会出现大量的贫血模型和静态函数,它们在面向对象编程中都是被批判的对象。即使团队已经达成一致,在新增功能时还是会第一时间想到多态,反复的讨论会消耗团队大量的精力。
总结
我们没有解决这两大顽疾的银弹,一两次培训解决不了问题。这时最笨的方法也许就是最有效的方法,要反复讨论和比较优缺点。