Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8 Java:函数式编程中是否禁止域对象使用实例方法?_Java 8_Functional Programming_Domain Driven Design_Immutability_Vavr - Fatal编程技术网

Java 8 Java:函数式编程中是否禁止域对象使用实例方法?

Java 8 Java:函数式编程中是否禁止域对象使用实例方法?,java-8,functional-programming,domain-driven-design,immutability,vavr,Java 8,Functional Programming,Domain Driven Design,Immutability,Vavr,既然函数式编程将数据和行为分开处理,并且行为不应该改变实例的状态,那么FP是否建议不要为域对象使用实例方法?或者我应该始终声明所有字段为最终字段吗? 在像Java这样的面向对象语言的上下文中,我要求更多 FP是否建议对域对象完全不使用实例方法 在《领域驱动设计》一书中,Eric Evans讨论了使用实体和价值对象对领域进行建模 值对象模式调用不可变的私有数据;初始化值对象后,它不会更改。在命令-查询分离语言中,我们可以说值对象的接口支持查询,但不支持命令 因此,值对象上的实例方法非常类似于,对象

既然函数式编程将数据和行为分开处理,并且行为不应该改变实例的状态,那么FP是否建议不要为域对象使用实例方法?或者我应该始终声明所有字段为最终字段吗? 在像Java这样的面向对象语言的上下文中,我要求更多

FP是否建议对域对象完全不使用实例方法

在《领域驱动设计》一书中,Eric Evans讨论了使用实体和价值对象对领域进行建模

值对象模式调用不可变的私有数据;初始化值对象后,它不会更改。在命令-查询分离语言中,我们可以说值对象的接口支持查询,但不支持命令

因此,值对象上的实例方法非常类似于,对象的不可变私有状态扮演捕获变量的角色

由于函数式编程分别处理数据和行为

我听说过很多,但不一定是真的。是的,它们在语法上是不同的,但是封装在FP中也是一件事。你不希望你的数据结构因为同样的原因被公开,你不希望它出现在OOP中,你希望它以后再发展。您希望添加或优化功能。一旦您允许直接访问数据,您就基本上失去了对该数据的控制

例如,在haskell中,有一些模块,它们实际上是单个单元中的数据+行为。通常情况下,外部函数无法使用数据的“构造函数”(即直接访问“字段”)。(与往常一样,也有例外。)

FP是否建议对域对象完全不使用实例方法

FP是一个范例,它说软件应该使用(数学)函数的(数学)组合来构建。基本上就是这样。现在,如果你眯着眼睛看得够多,你可以把一个方法叫做一个函数,只需要一个额外的参数
this
。只要一切都是不变的

所以我想说不,“FP”并没有明确定义语法,在某些条件下它可以与对象兼容

在像Java这样的面向对象语言的上下文中,我要求更多

这就是它变得模糊的地方。Java不太适合做函数式编程。请记住,它可能借用了传统FP语言的某些语法,但这并不意味着它适合FP


例如,不变性、纯函数、函数组合都是您应该做的事情,而Java没有这些。我的意思是,你可以编写代码来“假装”,但你会逆流而上。

你的字段应该是最终字段,但函数代码和实例方法并不是相互排斥的

以BigDecimal类为例:

BigDecimal x = new BigDecimal(1);
BigDecimal y = new BigDecimal(2);
BigDecimal z = a.add(b);

x和y是不可变的,add方法保持不变,并创建一个新的BigDecimal。

如何使用实例方法实现不可变的封装?我可以“小心”,但这在共享代码库中不够严格,我们必须有不能违反的规则。当然,如果我所有的变量都是final,那么我可能有实例方法,但除此之外,实例方法不是通向不可变冲突的网关吗?@GopalSAkshintala实例方法是一种未声明的方法
static
。这并不意味着该方法会进行修改。举一个简单的例子,
java.lang.String
有大量的实例方法,但仍然不能提供任何修改封装(可变)数组的方法,因此字符串仍然是不可变的。正如@Holger所说,您可以创建小的不可变对象,并让所有需要更改状态的方法只返回具有该状态的新对象,而不是就地修改它。然而,正如您准确指出的,在共享代码库中确实没有任何东西可以防止其他人弄乱您精心构建的功能代码。即使只是接受lambda或其他您无法控制的第三方对象,也可能会带来不可预见的副作用。在适当的FP语言中,这是不可能发生的,但在Java中,除了在小的隔离类中,实际上没有其他方法可以防止这种情况。