D 具有嵌套对象和生成器的不可变值对象
我们有一个大型系统,它有许多值对象,这些值对象目前被证明是不可变的,并且没有提供和方法来改变对象。在重写代码的某些部分时,我认为不仅要将类记录为不可变的,而且要将它们声明为不可变的,这将是一个很好的练习 具有嵌套对象的值对象如下所示:D 具有嵌套对象和生成器的不可变值对象,d,D,我们有一个大型系统,它有许多值对象,这些值对象目前被证明是不可变的,并且没有提供和方法来改变对象。在重写代码的某些部分时,我认为不仅要将类记录为不可变的,而且要将它们声明为不可变的,这将是一个很好的练习 具有嵌套对象的值对象如下所示: immutable class Nested { int i; public this(int i) immutable { this.i = i; } } immutable class Value {
immutable class Nested
{
int i;
public this(int i) immutable
{
this.i = i;
}
}
immutable class Value
{
private Nested nested_;
public immutable(Nested) nested() const
{
return this.nested_;
}
package this(immutable(Nested) nested)
{
this.nested_ = nested;
}
}
每当需要对任何值进行更改时,我们都使用生成器创建副本并修改属性。到目前为止还不错,但是当涉及到嵌套对象时,我遇到了麻烦。使用原始对象从生成器创建副本只能获取不可变的嵌套对象并将其存储。但是构建器如何将嵌套对象更改为新对象呢
我从std.typecons提出了可重新绑定的概念,但我不确定这是否是一个好的实践
class Builder
{
import std.typecons : Rebindable;
Rebindable!(immutable(Nested)) nested_;
this()
{
this.nested_ = null;
}
this(immutable(Value) value)
{
this.nested_ = value.nested;
}
public void nested(immutable(Nested) nested)
{
this.nested_ = nested;
}
public immutable(Value) value() const
{
return new immutable Value(this.nested_);
}
}
void main()
{
import std.stdio : writefln;
immutable value = new immutable Value(new immutable Nested(1));
writefln("i = %d", value.nested.i);
auto builder = new Builder(value);
immutable newNested = new immutable Nested(2);
builder.nested = newNested;
writefln("i = %d", builder.value.nested.i);
}
我是否过多地考虑了不变性和常量正确性
问候,
鲁尼您使用
可重新绑定
的解决方案是可以的,我认为这是实现这一点的最佳方法。另一种可能的解决方案是使嵌套的_uuu可变并使用强制转换,但这并不是那么优雅和安全:
class Builder
{
import std.typecons : Rebindable;
union
{
private Nested m_nested_;
immutable(Nested) nested_;
}
this()
{
this.nested_ = null;
}
this(immutable(Value) value)
{
this.nested_ = value.nested();
}
public void nested(immutable(Nested) nested)
{
this.m_nested_ = cast(Nested)nested;
}
public immutable(Value) value() const
{
return new immutable Value(this.nested_);
}
}