1

私が現在取り組んでいるシステムでは、ドメイン ビジネス ルールと永続性制約の検証を分離することで、SRP (と思います!) に従っています。使いすぎた顧客の例を使用してみましょう。システムのビジネス ルールを満たすには、顧客が有効な郵便番号、住所、名前を持っている必要があるとします。さらに、顧客が選択したユーザー名はすべての顧客で一意である必要があるとしましょう。これは永続性制約として定義します。次の「本番環境の準備ができていない」疑似コードを検討してください。

public interface IPersistenceValidator<T>
{
    bool IsValidForPersistence(T domainObj, IList<ValidationError> validationErrors);
}

public interface IValidatable
{
    bool IsValid(IList<ValidationError> validationErrors);
}

public class Customer : IValidatable
{
    public bool IsValid(IList<ValidationError> validationErrors)
    {
        //check for business rule compliance
    }
}

public class CustomerDao : IPersistenceValidator<Customer>
{
    public bool IsValidForPersistence(Customer domainObj, IList<ValidationError> validationErrors)
    {
        //check for persistence constraint compliance (user name is unique)
    }

    public bool SaveCustomer(Customer customer)
    {
        //save customer
    }
}

上記で定義されたクラスは、次のようにサービス クラスに接続される場合があります。

   public class SaveCustomerService
    {
        private CustomerDao _customerDao;

        public SaveCustomerService(CustomerDao customerDao)
        {
            _customerDao = customerDao;
        }

        public bool SaveCustomer(Customer customer)
        {
            IList<ValidationError> validationErrors = new List<ValidationError>();
            if (customer.IsValid(validationErrors))
            {
                if (_customerDao.IsValidForPersistence(customer, validationErrors))
                {
                    return _customerDao.SaveCustomer(customer);
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
    }

このアプローチに関する私の主な懸念は、CustomerDao の将来の消費者が、SaveCustomer() の前に IsValidForPersistence() を呼び出すことを知っている必要があることです。そうしないと、無効なデータが永続化されます。SQL レベルでこれを防ぐために DB 制約を作成することもできますが、それは面倒なように感じます。

IsValidForPersistence() を CustomerDao.SaveCustomer() に移動する必要があるようですが、SaveCustomer() の署名をリファクタリングして、ValidationErrors クラスへの参照を含める必要があります。大規模なリファクタリングに飛び込む前に、これらの問題に対処するための一般的な/推奨されるパターンについて、他のユーザーからフィードバックを得たいと思いました。

ありがとう

4

1 に答える 1

0
  • 次のような検証の問題を解決したい場合は、まずここをチェックしてください。

    public class Address {
    
        @NotNull private String line1;
        private String line2;
        private String zip;
        private String state;
    
        @Length(max = 20)
        @NotNull
        private String country;
    
        @Range(min = -2, max = 50, message = "Floor out of range")
        public int floor;
    
            ...
    

    }

    とにかく、データベースでユーザー名を確認する必要があります。検証をカスタマイズできます (データベースが一意であることを確認するなど)。詳細は別のリンクを参照してください。

  • 休止状態バリデーターを確認する
  • jbossの Validator フレームワークの使用を確認してください
  • Validation In The Domain Layer partIpartIIを読むことができます。これは Java ではありませんが、ロジックは重要です。
于 2009-12-16T15:00:53.550 に答える