验证域对象的持久性

发布于 2024-08-15 04:10:52 字数 2133 浏览 10 评论 0原文

在我当前正在开发的系统中,我遵循 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 级别防止这种情况,但这感觉就像是一个拼凑。

似乎 IsValidForPersistence() 应该移至 CustomerDao.SaveCustomer() 中,但随后我必须重构 SaveCustomer() 的签名以包含对 ValidationErrors 类的引用。在进行如此大的重构之前,我想从其他人那里获得一些关于处理这些问题的常见/首选模式的反馈。

谢谢

In the system I'm currently working on, I'm following SRP (I think!) by separating the validation of domain business rules vs persistence constraints. Let's employ the overused customer example. Say a customer must have a valid zip code, street address and name to satisfy the system's business rules. Let's further say that the customer's selected user name must be unique across all customers, which I define as a persistence constraint. Please consider the following "not ready for production" pseudo code:

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
    }
}

The classes defined above might get wired up into a service class as follows:

   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;
            }
        }
    }

My primary concern with this approach is that future consumers of CustomerDao must know to call IsValidForPersistence() before SaveCustomer(), otherwise invalid data gets persisted. I could create DB constraints to guard against this at the SQL levels, but that feels like a kludge.

It seems like IsValidForPersistence() should be moved into CustomerDao.SaveCustomer() but then I have to refactor the signature of SaveCustomer() to include references to the ValidationErrors class. Before I dive into that big of a refactoring, I wanted to get some feedback from others on common/preffered patterns for dealing with these issues.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

终难遇 2024-08-22 04:10:52
  • 如果您想解决验证问题,请先检查此处问题如;

    公共类地址{
    
        @NotNull 私有字符串 line1;
        私有字符串line2;
        私有字符串 zip;
        私有字符串状态;
    
        @长度(最大= 20)
        @NotNull
        私人字符串国家;
    
        @Range(min = -2, max = 50, message = "楼层超出范围")
        公共楼层;
    
            ...
    

    }

    无论如何,您必须检查数据库中的用户名。您可以自定义验证(例如去检查数据库是否唯一)。查看另一个详细链接。

  • 检查休眠 验证器
  • 检查使用验证器来自 jboss 的框架
  • 您可以阅读域层中的验证partI< /a>第二部分,这不是java 但逻辑很重要。
  • first check HERE if you want to solve your validation problem like;

    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;
    
            ...
    

    }

    anyway you must check username in database. You can customize your validation (like go and check DB for that is unique). Look at another links to detail.

  • Check hibernate validator
  • Check Using the Validator framework from jboss
  • You can read Validation In The Domain Layer partI, partII, this is not java but logic is important.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文