14

DDD 実践者がアドバイスするように、ビジネス ルールの検証はドメイン オブジェクト (エンティティ、値オブジェクト、およびドメイン サービス) 内に実装する必要があり、技術的な検証 (長さのチェック、正しい入力形式、正しいデータ型、...) ドメインモデルの外、およびドメインオブジェクトを明確に保つためのアプリケーション層のような場所。

私の質問はこれです:

クレジット カード番号の値オブジェクトがある場合、技術的な検証を値オブジェクトから除外する必要がありますか? 言い換えれば、「自己検証済み」という用語は、値オブジェクトを扱う際の技術的検証には関与していませんか?

間違ったデビット カード番号や電子メール アドレスがビジネス ルールに違反する可能性がある場合はどうすればよいでしょうか。

より明確にするために、デビット カード番号を表す次の値オブジェクトに注目してください。

    public class DebitCardNumber : ValueObject
{
    public string Number { get;private set; }

    public CreditCardNumber(string number)
    {
        Validation(number);

        this.Number = number;
    }

    private void Validation(string number)
    {
        if (String.IsNullOrWhiteSpace(number))
        {
            throw new CardNumberCanNotBeEmptyException();
        }

        if (number.Length != 16)
        {
            throw new CardNumberLengthMustBeSixteenDigitException();
        }

        int sum = 0;
        for (int i = 1; i <= 16; i++)
        {
            if (!char.IsDigit(number[i - 1]))
            {
                throw new ValueContainsSomeNonDigitCharacterException();
            }

            int m = (i % 2 == 0 ? 1 : 2);
            int a = (int.Parse(number[i - 1].ToString()) * m);

            while (a > 9)
            {
                a -= 9;
            }

            sum += a;
        }

        if ((sum % 10) > 0)
        {
            throw new ValueIsNotCorrectAsACardNumberException() 
                { Message = "Perhaps some digits has been entered in wrong order or they are incorrect." };

        }
    }
}

このコードによると、アルゴリズムを実行してカード番号の形式が正しいかどうかを確認する Validation メソッドがあります。このタイプの検証に適した場所だと思いますか?

4

4 に答える 4

15

DDD 実践者がアドバイスするように、ビジネス ルールの検証はドメイン オブジェクト (エンティティ、値オブジェクト、およびドメイン サービス) 内に実装する必要があります。

はい。

また、技術的な検証 (長さのチェック、正しい入力形式、正しいデータ型など) をドメイン モデルの外に配置し、ドメイン オブジェクトを明確に保つためにアプリケーション層のような場所に配置する必要があることを読んだことがあります。

ここで少し混乱します。重要な点は、エンティティが一連の入力検証について心配する必要はないということです。それは彼らの仕事ではありません (責任の分離)。したがって、生データ (文字列、プリミティブ) をモデルのエンティティに渡す代わりに、最初にプリミティブを使用して、エンティティが認識する値の型を構築し、次にそれらのエンティティを渡します。

整形式の値型を作成するためにプリミティブを使用できるルールは、値型自体 (コンストラクター) またはその目的のために提供される専用のファクトリ内で適切に実装されます)。アプリケーション コンポーネントには、受信したメッセージ/DTO から値の型を作成してから、その値をモデルに渡す責任があります。

したがって、あなたの例では、DebitCard 検証ロジックは適切な場所にあるように見えます。

注意 - モデルは時間とともに進化します。モデルが変更された場合でも、以前のバージョンのモデルによって書き込まれたデータを読み取ることができる必要があります。現在のデータを無効として扱う検証ルールを追加すると、面倒になる可能性があるため、検証ルールにビジネス上の動機があることを確認する必要があります。デビットカード番号に有効なチェックサムがあることを確認することで、お金を節約したり、コストを削減したりしていますか?

(例: 顧客が無効なカード番号で注文書を送信したとします。企業はその注文を拒否したいですか、それとも注文を受け入れたが、有効な支払い方法が提供されるまで行動を延期したいですか?後者の選択の場合、あなたは検証ロジックが注文の受け入れの邪魔にならないようにする必要があります)。

于 2016-08-30T18:07:32.463 に答える
4

クレジット カード番号などの値オブジェクトがある場合でも、技術的な検証を値オブジェクトから除外する必要がありますか? 言い換えれば、「自己検証済み」という用語は、値オブジェクトを扱う際の技術的検証には関与していませんか?

正しい。ドメイン (エンティティ、ドメイン サービス、vos など) は、技術的な問題ではなく、ビジネスルールを適用するようにモデル化する必要があります。ドメインで DebitCards と CreditCards を区別する必要があるかもしれませんが、ビジネスがカード番号自体の形式を気にしているとは思えません。カード番号のフォーマットと正確性はインフラストラクチャの目的にとって重要であるため、そのレイヤーでフォーマット規則を適用できます。

于 2017-08-22T04:12:51.830 に答える
1

私の意見では、あなたのアプローチはほとんどの場合正しいです。

番号が有効でない場合、実際にはデビット カード番号ではありません。

有効でないデビット カード番号を持っているとします。ブール値validが false に設定されているか、コードが嘘をついています:デビット カード番号ではありません

セキュリティや UX の目的で数値を保存したい場合は、入力フォームの値オブジェクト内など、別のオブジェクトに保存する必要があります。

于 2016-08-30T10:08:19.450 に答える
1

私はあなたの例を技術的な検証ルールとは考えていません-それはデビットカードのドメインルールだと思います-銀行のドメインでデビットカード番号が特定のパターンに従わなければならない場合、これはドメインルールです強制する必要があります。

あなたの解決策は正しいと思います。

于 2016-08-30T10:13:44.783 に答える