更新:Reposted on Programmers Stack Exchange主にオピニオンベースとして保留されているためです。構造体を使用して組み込み型の検証を強制するための賛否両論
一般的に、ドメインオブジェクトは、組み込み型で表現できますが、有効な値はその型で表される値のサブセットです。
このような場合、組み込み型を使用して値を格納できますが、値が入力時点で常に検証されるようにする必要があります。そうしないと、無効な値で処理される可能性があります。
これを解決する1つの方法は、struct
というカスタムとして値を格納することです。これは、組み込み型の1つのprivate readonly
バッキングフィールドを持ち、そのコンストラクタが指定された値を検証します。このstruct
タイプを使用して、常に検証された値のみを使用することができます。
また、キャスト演算子を基になる組み込み型との間で提供することによって、値が基になる型としてシームレスに入力および終了できるようにすることもできます。
例として、ドメインオブジェクトの名前を表す必要があり、有効な値は1〜255文字の長さの任意の文字列です。
public struct ValidatedName : IEquatable<ValidatedName>
{
private readonly string _value;
private ValidatedName(string name)
{
_value = name;
}
public static bool IsValid(string name)
{
return !String.IsNullOrEmpty(name) && name.Length <= 255;
}
public bool Equals(ValidatedName other)
{
return _value == other._value;
}
public override bool Equals(object obj)
{
if (obj is ValidatedName)
{
return Equals((ValidatedName)obj);
}
return false;
}
public static implicit operator string(ValidatedName x)
{
return x.ToString();
}
public static explicit operator ValidatedName(string x)
{
if (IsValid(x))
{
return new ValidatedName(x);
}
throw new InvalidCastException();
}
public static bool operator ==(ValidatedName x, ValidatedName y)
{
return x.Equals(y);
}
public static bool operator !=(ValidatedName x, ValidatedName y)
{
return !x.Equals(y);
}
public override int GetHashCode()
{
return _value.GetHashCode();
}
public override string ToString()
{
return _value;
}
}
の例では、このようimplicit
としてツーstring
キャストが失敗することはできません示していますが、このようexplicit
としてfrom- string
キャストが無効な値のためにスローされますが、もちろんの:私たちは、次の構造体を使用して、これを表すことができこれらはいずれもimplicit
またはexplicit
のいずれかです。
string
からのキャストによってのみこの構造体を初期化することができますが、IsValid
static
メソッドを使用してそのようなキャストが先に失敗するかどうかをテストできます。
これは、単純なタイプで表現できるドメイン値の検証を強制するのに適しているようですが、頻繁に使用されたり、示唆されたりしません。理由について興味があります。
私の質問は、このパターンを使用することのメリットとデメリットは何ですか?
このパターンが悪いと思うなら、私は理由を理解したいと思っています。また、あなたが感じるものが最良の選択肢です。
私のバリデータには、特定の名前空間のファクトリクラスまたは静的クラスのいずれかを介してアクセスできるドメインロジックです。つまり、すべての検証を含む 'ClientValidator'のような名前空間内の' MyApp.Validators'とクラス固有のバリデータです。私は実際に構造体の使用を見ていない – Franck
プログラマに移行する候補者はおそらく、確かにただの意見ではない –
私は私の答えを提供するだろうが、Q&Aを得るためにremaning 1近い投票で閉鎖.. .... –