Java 继承设计模式的不变性
我正在用Scala实现一些代码,遵循Java教程 本教程中有一段代码,可以最小化为以下内容:Java 继承设计模式的不变性,java,scala,design-patterns,immutability,Java,Scala,Design Patterns,Immutability,我正在用Scala实现一些代码,遵循Java教程 本教程中有一段代码,可以最小化为以下内容: public abstract class A { private int id; public A(String name) { id = Helper.getId(name); fetchAllAttributes(); } protected abstract void fetchAllAttributes(); pro
public abstract class A {
private int id;
public A(String name) {
id = Helper.getId(name);
fetchAllAttributes();
}
protected abstract void fetchAllAttributes();
protected int fetchAttribute(String attribute) {
Helper.getAttribute(id, attribute);
}
public class B extends A {
int volume;
public B() {
super("B");
}
@Override
protected void fetchAllAttributes() {
volume = super.fetchAttribute("volume");
}
}
}
这就是将其转换为Scala时的样子:
abstract class A(val name: String) {
private val id = Helper.getId(name)
fetchAllAttributes()
protected def fetchAllAttributes(): Unit
protected def fetchAttribute(attribute: String): Int = {
Helper.getAttribute(id, attribute)
}
class B() extends A("B") {
var volume = 0
override protected def fetchAllAttributes(): Unit = {
volume = super.fetchAttribute("volume")
}
}
}
这里我想问两个问题:
val
s我不知道这个图案的名字。在不知道模式的目标的情况下,很难准确地知道如何将其转换为不变的样式,但如果你足够努力地眯着眼睛,这里有一些类似的东西:
class FactoryFromAttributes[A](name: String) {
def construct(f: (String => Int) => A): A = {
val id = Helper.getId(name)
f(str => Helper.getAttribute(id, str))
}
}
class B(volume: Int)
object B extends FactoryFromAttributes[B]("B") {
def apply(): B = construct { fetchAttribute =>
new B(fetchAttribute("volume"))
}
}
对我来说,这种逻辑在伴生对象中更有意义,所以我将它移到了伴生对象中,而不是在生成的构造类中保留一个奇怪的子类关系。构造函数之外的初始化逻辑很少适合于良好的不可变样式
没有通用的方法将任何可变代码转换为不可变代码。您需要解释可变代码解决了什么问题,然后人们将能够帮助找到解决问题的不可变方法。从基类构造函数调用可重写方法(更不用说抽象方法)在Java中是一种反模式。子类的方法将在子类构造函数执行之前执行,这可能会导致各种问题。有关详细信息,请参阅。正确的处理方法是不公开任何公共构造函数,而是定义一个工厂方法,在对象完全构造后调用对象的
fetchAllAttributes()
方法。