用于验证数据和创建对象的设计模式 [英] What design pattern to use for validating data and creating an object

查看:108
本文介绍了用于验证数据和创建对象的设计模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常遇到这样的情况:我想通过传递给定数据或另一个对象来创建对象的实例,但是该数据或对象需要有效或处于正确的状态。对于这种正确的方式,我总是不太清楚。这是我的示例:

I often come across situations where a I want to create an instance of an object by passing it some given data or maybe another object but the data or object needs to be valid or in the right state. I am always a bit unclear on the 'correct' way of doing this. Here is my example:

给出此类:

class BusinessObject()
{
    const Threshold = 10;

    public BusinessObject(SetOfData<SomeType> setofdata)
    {
        // an example of some validation
        if (setofdata.count > Threshold)
        {
            // performance some business logic
            // set properties
        }
    }
}

如果这样做,可能会遇到一些问题:

It is possible to run into some problems if you do this:

var setofdata = new SetOfData<SomeType>();

// if data is not valid then the object will be created incorrectly
var businessObject = new BusinessObject(setofdata);

所以我的解决方案一直是:

So my solutions have always been either:

class BusinessObjectBuilder()
{
    public BusinessObject Build(SetOfData<SomeType> setofdata)
    {
        // an example of some validation
        if (setofdata.count > Threshold)
            return new BusinessObject(setofdata);
        }
        else
        {
            return null;
        }
    }
}

或者将构造函数设为私有并添加静态工厂方法:

Or make the constructor private and add a static factory method:

class BusinessObject()
{
    const Threshold = 10;

    public static Create(SetOfData<SomeType> setofdata)
    {
        if (setofdata.count > Threshold)
        {
            return new BusinessObject(setofdata);
        }
        else
        {
            return null;
        }
    }

    private BusinessObject(SetOfData<SomeType> setofdata)
    {
        // performance some business logic
        // set properties
    }
}

理想情况下,我不想抛出异常数据无效,因为可能在一个流程中创建了多个业务对象,而且我不希望如果一次验证失败并且捕获和抑制异常情况不好,整个流程就会失败。

ideally I would not like to throw an exception if the data is invalid as there might be multiple business objects being created in one process and I don't want the whole process to fail if one validation fails and catching and suppressing exceptions is not good.

我阅读的所有有关Abstract Factory或Factory方法的示例都涉及传入某种类型或枚举以及正在构建和返回的正确对象。他们似乎从未涵盖过这种情况。

Also all examples I read of the Abstract Factory or Factory method involve passing in some type or enum and a correct object being built and returned. They never seem to cover this scenario.

那么在这种情况下有哪些约定?任何建议将不胜感激。

So what are the conventions in this scenario? Any advice would be greatly appreciated.

推荐答案

IMHO构造函数验证对于需要确保无对象的许多情况是最佳的

IMHO constructor validation is the best for many situation where you need to make sure that no object can be created unless specified parameter being set.

public class BusinessObject
{
    const Threshold = 10;

    public BusinessObject(SetOfData<SomeType> setofdata)
    {
        // an example of some validation
        if (setofdata.count > Threshold)
        {
            throw new InvalidOperationException("Set data must be above treshold");
        }
    }
}

但是,这种方法的实现很差时间:

However, this has bad implementation when:


  • 您可能有无效对象,例如处于草稿状态的时间等

  • 需要默认构造函数时的ORM

  • 如果发生繁琐的验证逻辑。

第1点和2,除了请求-验证-提交机制外,我不能建议其他任何选择。

For point no.1 and 2, I cannot suggest any other option except request - validate - submit mechanism.

对于第3点,原因是该类将为验证做太多工作本身并创建一个整体代码。如果验证逻辑很多,我建议使用注入的验证器实现构建器模式,并使内部 BusinessObject 的构造函数成为内部。

For point no.3, the reason is, the class will do too much for validation itself and creating a monolithic code. If there is much validation logic, I suggest to implement builder pattern with injected validator, and make the constructor of BusinessObject internal.

public class BusinessObjectBuilder
{
    public BusinessObjectBuilder(IBusinessObjectValidator validator){
        this.validator = validator;
    }
    IBusinessObjectValidator validator;

    public BusinessObject Build(SetOfData<SomeType> setofdata)
    {
        // an example of some validation
        if (validator.IsValid(setofdata))
            return new BusinessObject(setofdata);
        }
        else
        {
            throw new //exception
        }
    }
}

这将强制执行模块化编程并防止使用整体代码。

This enforce modular programming and prevent monolithic code.

这两个代码都是:


  • 易于测试

  • 易于审核

  • 可扩展

这篇关于用于验证数据和创建对象的设计模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆