2016-03-23 4 views
0

現在、不変であると文書化されていて、オブジェクトを変更するメソッドやメソッドを持っていない多くの値オブジェクトを持つ大きなシステムがあります。コードのいくつかの部分を書き直しながら、私は、クラスを不変であると文書化するだけでなく、不変であると宣言することが良い練習になると考えました。入れ子オブジェクトとビルダーを持つ不変値オブジェクト

ネストされたオブジェクトと値オブジェクトは、次のようになります。

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からRebindableを思いついた - しかし、これは良い練習であるかどうかは分かりません。

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); 
} 

私は不変性とconstの正確さについてあまりにも多くのことを考えていますか?

よろしく、

ルーニー

答えて

0

RebindableとあなたのソリューションはOKです、と私はこれをachiveするための最良の方法として、それをconsidere。もう一つの可能​​な解決策は、ネストされた_を変更可能にしてキャストを使用することですが、これはあまりエレガントで安全ではありません:

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_); 
    } 
} 
関連する問題