函数式编程、OOP 和数据隐藏

mos*_*dve -3 oop functional-programming

每个人都说函数式编程可能比 OOP 更好,因为它具有不变性。好的,但是 FP 如何比 OOP 更好地隐藏或组织数据?如果我知道 OOP 被引入来解决这个问题,因为过程范式做得不够好。FP 有什么用?

如果您以良好的方式使用 OOP 并且不编写贫血风格的类和可变对象,那么 FP 是否仍然是比 OOP 更好的日常编程任务选择?

Ric*_*nne 5

TL; 博士

函数式编程与封装无关,但大多数现代函数式语言都支持封装。

无论采用何种范式,封装(您称之为“数据隐藏”)都是现代编程的重要组成部分。在开发库时,您希望对库的用户隐藏部分代码。

面向对象的一面

OOP 语言允许您定义私有的东西:属性、方法、类等等。私有的东西不能从外部作用域访问,仅此而已。

# Ruby

class A
  def a
    # This is public
  end

  private

  def b
    # This is private
  end
end
Run Code Online (Sandbox Code Playgroud)

模块化方面

模块化语言使用模块代替类,但它们几乎相同。您可以将模块接口与实现分开定义。

(* OCaml *)

module A : sig
  (* Here is the interface *)
  val a : int -> int
end = struct
  (* Here is the implementation *)
  let a = (* This is public *)
  let b = (* This is private *)
end
Run Code Online (Sandbox Code Playgroud)

如您所见,模块化语言在封装事物方面与 OOP 语言一样出色。

功能方面

简单来说,函数式语言就是不使用变异的语言。当然,更真实的定义会复杂得多。

让我们看一个例子:

# Python

def sum(l):
  sum = 0
  for e in l:
    sum += e # Mutations occur here
  return sum
Run Code Online (Sandbox Code Playgroud)

并以函数式风格,即没有任何突变:

(* OCaml *)

let rec sum l =
  match l with
  | [] -> 0
  | h::t -> h + sum t
Run Code Online (Sandbox Code Playgroud)

函数式风格相对于命令式风格的好处有待讨论,但我现在将把它们排除在外。

把这一切放在一起

事实上,语言不必在模块化、OOP 或函数式之间做出选择。从上面可以看出,这三个概念确实彼此不同,而语言只是倾向于将这些特性结合起来。

例如,OCaml主要是功能性和模块化的,但它也支持 OOP 和命令式风格,这样您就可以充分利用所有领域,前提是您知道自己在做什么。(这是“能力越大责任越大”之类的东西。)

因此,为了回答您的问题,函数式编程本身与封装数据无关,但函数式语言提供了类或模块等特性来为它们做这件事。