2

私は不変性の概念が好きです。また、null を使用しないというコンセプトも気に入っています (可能であれば、NullDesignPattern も NullObjects も可能な限り使用しません)。

しかし、次のシナリオはどうでしょうか。

私は 2 つのフィールドを持つ object を持っていUserます: birthdayand dateInLifeMarried(同様のフィールドである可能性があります。重要なことは、最初はこのフィールドがnulland であり、オブジェクトの寿命のある時点で変化することです)。

不変であるため、両方のフィールドをコンストラクターに含める必要があります。

public User(birthday, dateInLifeMarried)

今:

  1. null2 番目のパラメーターに渡したくありません
  2. 不変であるため、セッターを追加したくありません
  3. 代わりに NullObjectPattern でコンストラクターを呼び出したくありませんnull

私は自分自身と矛盾しているだけですか、それとも私が考えていないエレガントな方法はありますか?

4

4 に答える 4

13

コンストラクターの署名だけでなく、表現をどうしたいかを検討する必要があります。フィールドにnull参照(または少なくとも同様のもの)を使用する必要があると思います。ただし、次の 2 つのコンストラクターを使用できます。

User(birthday)               // Unmarried user
User(birthday, marriageDate) // Married user; marriageDate must not be null

API のユーザーとして、それが本当に好きかどうかはわかりませんが、むしろmarriageDatenull を許可したいと思います。特に、次のように書かなければならないのは煩わしいでしょう:

LocalDate marriageDate = getMarriageDateOrNull();
User user = marriageDate == null ? new User(birthday)
                                 : new User(birthday, marriageDate);

または、人々は複数回結婚する可能性があるため、いつでも を取得できますIterable<LocalDate> marriageDates。その後、結婚していないユーザーは空のシーケンスになります:) (ただし、結婚して離婚したユーザーと結婚して寡婦になったユーザーを考慮する必要があります)実生活をモデル化するのは難しいです。)

于 2013-02-20T09:47:36.093 に答える
1

2番目のコンストラクタはどうですか

User(birthday)

それが最初に呼び出す

this(birthday, null)

?

于 2013-02-20T09:49:41.120 に答える
1

null を避けるためだけに避けないでください。意味を考えて、null意味のあるところで使いましょう。値nullは、不明未定義、または未指定の値を表します。null を意識的に使用すると、コードを使いやすく読みやすくすると同時に、null ポインター例外を防ぐことができます。

あなたの例では、結婚日が指定されていない可能性があるため、許可する必要がありますnull。ただし、誕生日を未指定にしたくないため、null を許可しません。次のようにコンストラクタを指定できます。

User(LocalDate birthday)
{
    this(birthday, null);
    // That's it! Nothing more to do here.
}

User(LocalDate birthday, LocalDate marriageDate)
{
    if (birthday == null)
        throw new IllegalArgumentException();
    // Use it...
}

これで、あなた (またはあなたのコードを使用する人) は次のようなことができます:

LocalDate marriageDate = getMarriageDateOrNull();
User user = new User(birthday, marriageDate);

見る?コードを回避するのではなく を与えるため、コードがよりクリーンになります。null

于 2013-02-20T10:50:04.743 に答える
0

継承を使用できます:

public abstract class User{}
public class UnMarriedUser extends User{}
public class MarriedUser extends User{}

しかし、このモデルは、多くの順列に直面すると、貧弱で弱くなります。

于 2013-02-20T09:52:43.763 に答える