Oop 在何处验证类型创建参数

Oop 在何处验证类型创建参数,oop,design-patterns,Oop,Design Patterns,我已经看到并使用了各种不同的方法来创建对象,但在验证创建同一对象所需的数据时,还没有找到任何可以遵循的模式 也就是说,你更喜欢的方式是什么 public SomeClass(Product product, Device device, PlatformType platformType, User user, Country country) { if (environment == null || environment.Id == 0) throw new ArgumentNull

我已经看到并使用了各种不同的方法来创建对象,但在验证创建同一对象所需的数据时,还没有找到任何可以遵循的模式

也就是说,你更喜欢的方式是什么

public SomeClass(Product product, Device device, PlatformType platformType, User user, Country country)
{
    if (environment == null || environment.Id == 0) throw new ArgumentNullException("environment");
    if (device == null || device.Id == 0) throw new ArgumentNullException("device");
    if (country == null) throw new ArgumentNullException("country");
    if (userContext == null) throw new ArgumentNullException("userContext");
    if (platformType == null) throw new ArgumentNullException("platformType");

    Product = product;
    Device = device;
    PlatformType = platformType;
    UserContext = userContext;
    Country = country;
}


根据Fail fast原则,这两种方法似乎都是正确的,我只是不确定第一种方法,因为如果要创建一个对象,在您尝试创建它之前验证所有要使用的数据是有意义的,而且因为您希望重用验证,工厂模式更有意义,但也许这只是口味的问题。

首先,我对这种验证不是很熟悉

以下是我对不同解决方案的看法:

工厂 专业人士

  • 如果许多实现需要相同的验证,请将验证重新组合到一个位置
缺点

  • 它不会阻止某人直接构造对象(不修改您提供的类)
  • 您只有一个实现,因此工厂的责任(根据一些论点提供良好的实现)是无用的
建设者 专业人士

  • 允许您以“流畅的风格”创建对象(它真的是专业的吗?)
缺点

  • 这可能会破坏
    SomeClass
    的潜在不稳定性。免责声明:我支持不可变类
  • 由于您只有一个没有可选参数的构造函数,因此构建器似乎没有用处
验证器 您可以将责任委托给包含一些规则的验证器(在您的情况下,只有一个规则:
ObjectNotNull

推卸责任 在这种情况下,提供一致参数的责任可能由调用方承担。如果
SomeClass
仅在内部使用,您可以假设

也许这不是责任 毕竟,我的第一个假设可能是错误的,执行一些空检查本身并不是一项责任,但您可以将其视为“修补调用方代码的某些弱点,因为他太懒了,不提供非空值”。因此,您的第一个解决方案似乎是完全合法的


希望我的想法能对您有所帮助。

首先,我对这种验证不太熟悉

以下是我对不同解决方案的看法:

工厂 专业人士

  • 如果许多实现需要相同的验证,请将验证重新组合到一个位置
缺点

  • 它不会阻止某人直接构造对象(不修改您提供的类)
  • 您只有一个实现,因此工厂的责任(根据一些论点提供良好的实现)是无用的
建设者 专业人士

  • 允许您以“流畅的风格”创建对象(它真的是专业的吗?)
缺点

  • 这可能会破坏
    SomeClass
    的潜在不稳定性。免责声明:我支持不可变类
  • 由于您只有一个没有可选参数的构造函数,因此构建器似乎没有用处
验证器 您可以将责任委托给包含一些规则的验证器(在您的情况下,只有一个规则:
ObjectNotNull

推卸责任 在这种情况下,提供一致参数的责任可能由调用方承担。如果
SomeClass
仅在内部使用,您可以假设

也许这不是责任 毕竟,我的第一个假设可能是错误的,执行一些空检查本身并不是一项责任,但您可以将其视为“修补调用方代码的某些弱点,因为他太懒了,不提供非空值”。因此,您的第一个解决方案似乎是完全合法的


希望我的想法能帮助你。

根据《规则》,你不应该把验证自己的责任交给类(否则类就不能承担任何其他责任)。最好让另一个类负责验证(或者像你提到的那样,可能只是一个方法工厂)。@谢谢你的评论。这正是我所想的,但在同一点上,假设您的类只有一个构造函数,并且在同一命名空间中没有任何其他类型,您可以“重用工厂进行创建,您还会使用单个方法创建工厂吗?”?我也可以为该对象使用构建器模式,并在构建方法中应用验证,但再说一次,如果目标只有一个构造函数,那么使用构建类型有意义吗?你是对的,工厂或构建器都不应该对此负责(加上在你的上下文中,实现没有意义)。我将发布一个关于我将如何进行验证的答案。根据,您不应该将验证自己的责任交给类(否则,您的类就不能承担任何其他责任)。最好让另一个类负责验证(或者像你提到的那样,可能只是一个方法工厂)。@谢谢你的评论。这正是我所想的,但在同一点上,假设您的类只有一个构造函数,并且在同一命名空间中没有任何其他类型,您可以“重用工厂进行创建,您还会使用单个方法创建工厂吗?”?我也可以为该对象使用构建器模式,并在构建方法中应用验证,但再说一次,如果目标只有一个构造函数,那么使用构建类型有意义吗?你是对的,工厂或构建器都不应该对此负责(加上在你的上下文中,实现没有意义)。我将发布一个如何进行验证的答案。有一些方法可以“防止”在工厂范围外创建对象,但不是完全防止,但是您可以使用分部类并设置目标类
public static class SomeClassFactory()
{
    public static SomeClass Create(Product product, Device device, PlatformType platformType, User user, Country country)
    {
        if (environment == null || environment.Id == 0) throw new ArgumentNullException("environment");
        if (device == null || device.Id == 0) throw new ArgumentNullException("device");
        if (country == null) throw new ArgumentNullException("country");
        if (userContext == null) throw new ArgumentNullException("userContext");
        if (platformType == null) throw new ArgumentNullException("platformType");
    }

    return new SomeClass(product, device, platformType, user, country);
}