在哪里验证类型创建参数

Where to validate type creation parameters

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

也就是说,首选的方法是什么?

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

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

根据 Fail-fast 原则,这两种方法似乎都是正确的方法,我只是不确定第一种方法,因为如果您要创建一个对象,那么验证您创建的所有数据是有意义的在您甚至尝试创建它之前就使用它,并且因为您想重用该验证,所以工厂模式更有意义,但也许我们只是个人喜好问题。

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

这些是我对不同解决方案的看法:

工厂

优点

  • 在许多实施需要相同验证的情况下,将验证重新组合在一个地方

缺点

  • 不会阻止别人直接构造对象(不修改你提供的class)
  • 你只有一个实现,因此工厂的责任(根据一些参数提供好的实现)是无用的

建设者

优点

  • 允许你在"fluent-style"中创建对象(真的很专业吗?)

缺点

  • 这可能会破坏 SomeClass 的潜在不变性。免责声明:我赞成不可变 classes
  • 由于您只有一个没有可选参数的构造函数,因此该构建器似乎毫无用处

验证者

您可以将责任委托给包含一些规则的验证器(在您的情况下只有一个规则:ObjectNotNull)。

拒绝责任

在这种情况下,提供一致参数的责任可能会留给调用者。如果 SomeClass 仅在内部使用,您可以假设。

也许这不是责任

毕竟,我的第一个假设可能是错误的,执行一些 null 检查本身并不是一项责任,但您可以像 "patching some weakness of the caller's code because he's too lazy for not providing non-null values" 一样看待它。因此,您的第一个解决方案似乎完全合法。

希望我的想法能帮到你。