2011-06-25 8 views
2

SQL Serverデータベースに登録される特定のオブジェクトに関する情報を含むクラスを設計しました。私はこのオブジェクトを(深く)不変にしたいと思っていますが、一度だけ登録されることを保証しなければなりません。このオブジェクトが次のパターンを実装する場合、それはまだ不変であると見なすことができますか?そのようなオブジェクトは不変であると見なすことができますか?

public class NewClass 
{ 
    private bool registered; 

    public string SomeProperty { get; private set; } 

    public NewClass Register() 
    { 
     if (registered) 
     { 
      throw new NotImplementedException(/*arguments*/); 
     } 

     /* Register on DB here... */ 
     registered = true; 
     return new NewClass(somePropertyFromDB); 
    } 

    public NewClass(string someProperty) 
    { 
     registered = false; 
     SomePropery = someproperty; 
    } 
} 

私はブールフィールドregistered以外のオブジェクトは不変であるが、それは実際にRegisterメソッドが実行される最初の時間に変更されますので、このフィールドは私にいくつかの疑問を残して...誰が教えてくださいできることを言うだろう私はどうすればこの問題を解決し、オブジェクトを不変にすることができますか?

答えて

3

いいえ、それは間違いなくではなく、不変です。 registeredの値は、オブジェクトの存続期間にわたって変化します。

それは不変にするには、オブジェクトの存続期間にわたって変化するregisteredフィールドを許可してはいけない - その代わり、Registerリターン私も削除したいregistered

ためtrue値を持つ新しいオブジェクトを作りますSomePropertyのプライベートセッターです。ちょうどゲッターとreadonly変数を持っています。

したがって、このような何か:

public class NewClass 
{ 
    private readonly bool registered; 
    private readonly string someProperty; 

    public bool Registered { get { return registered; } } 
    public string SomeProperty { get { return someProperty; } } 

    public NewClass Register() 
    { 
     // Note the change of exception here 
     if (registered) 
     { 
      throw new InvalidOperationException("Already registered"); 
     } 

     return new NewClass(somePropertyFromDB, true); 
    } 

    // You may want to have a public constructor with just someProperty 
    // which calls this one, which you could make private 
    public NewClass(string someProperty, bool registered) 
    { 
     this.registered = registered.; 
     this.someProperty = someproperty; 
    } 
} 

いくつかの注意:

  • 別のオプションは、2つの別々のクラス、RegisteredFooUnregisteredFooを持っているだろう。このクラスを使用してコードを理解しやすくするかもしれません
  • Registerを2回呼び出すことは誰も止めるものではありません。したがって、これを不変にすることは、冪等の点ではあまり役に立ちません。自然な副作用(データベースとの会話)があるため、これを本当に機能させるのは難しいです。
+0

あなたの答えはありがたいですが、 'SomeProperty'の設定者は' private'とマークされています。そして、 '登録された'問題の解決法に関しては、そういう意味でも、ユーザーが 'Instance1.Register();を書くことはできません。 Instance1.Register() 'どちらも新しいオブジェクトを返しますが、元の参照を保持しているので、メソッドを何度も実行できます。 – User

+0

@ユーザー:はい、私はちょうどそれに気付き、私の答えを編集しました。さらに編集中... –

関連する問題