我想替换(可变)类
class OldValue {
private int value;
public OldValue(int value) { this.value = value; }
public int getValue() { return value; }
public void setValue(int value) { this.value = value; }
}
使用不可变类
class NewValue {
private final int value;
public NewValue(int value) { this.value = value; }
public int getValue() { return value; }
/* no setter, obviously */
}
在大部分代码中 newValue.set(777)
可以替换为 newValue = new NewValue(777)
. 但是,代码中有一些遗留部分
class ManagementServiceProviderFacadeSingletonAbstractFactoryObserver {
public void setTheValue(OldValue oldValue) {
oldValue.setValue(555);
}
}
class Data {
private OldValue oldValue;
public OldValue get() { return oldValue; }
}
class SomewhereElse {
public void frobnicate(Data data, ManagementServiceProviderFacadeSingletonAbstractFactoryObserver x) {
x.setTheValue(data.get());
}
}
这些遗留部分很难更改,我们希望尽可能少地进行调整。有没有一种方法可以编写某种可以在遗留代码中使用的“邪恶”setter方法?像这样的
class EvilSetter {
public static void evilSet(NewValue newValue, int x) {
// temporarily make newValue.value both public and non-final, set it to x
}
}
有没有别的办法不失去新设计的不变性和优雅?
1条答案
按热度按时间wvyml7n51#
我可能会保留这两种类型,保留使用旧类型的遗留代码,并提供用于在这两种类型之间转换的适配器方法。
清楚地记录这些应该只用于与遗留代码接口,根据需要标记为不推荐使用。这显然不理想,但这适用于整个情况。
如果类更复杂(例如,还有一些具有非平凡行为的方法),那么它可能值得实现
OldValue
通过 PackageNewValue
,但在这个简单的例子中,这不会带来太多好处。我强烈建议不要使用任何反射黑客,因为它们首先会使使用不可变类型的大多数好处失效。不要给我一个看起来不可变的类型,然后以某种方式偷偷地更改值—这会打破用户的期望并隐藏竞争条件的风险。