如何验证工厂方法?

时间:2018-09-10 10:37:43

标签: c# oop exception domain-driven-design factory-method

如何验证工厂方法(对象的构造)。

  public static readonly byte MaxWorkDayHours = 12;

  public static WorkTime Create(Guid WorkTimeRegulationId, String name, byte numberOfHours, byte numberOfShortDays, ICollection<WorkTimeActivation> activations = null)
        {
            if (activations == null) { activations = new List<WorkTimeActivation>(); }
            if (numberOfHours > MaxWorkDayHours) return null;
            return new WorkTime()
            {
                Name = name,
                NumberOfWorkHours = numberOfHours,
                NumberOfShortDays = numberOfShortDays

            };
        }
  • 可以检查特定字段的大小是否可以大于 具体号码?还是这种验证类型应该在MVC的模型中而不是在域层中?还是两者皆有?
  • 如果我像这样if (numberOfHours > MaxWorkDayHours)进行检查,是否应该抛出异常numberOfHours reach the limit或返回null?

3 个答案:

答案 0 :(得分:2)

  

可以检查特定字段不能大于特定数字吗?

是的-当我们使用领域不可知类型(例如字节)来表达某些领域特定概念时,这是正常的事情。

  

这种类型的验证应该在MVC模型中,而不是在域层中吗?

肯定是域名层;但在模型中执行此操作可能也很有意义。在模型中检查值约束的动机是希望限制代码中需要检查的不同位置的数量。

中常见的一种模式是引入表示域概念的Value Object;该检查是在创建该值的构造函数(或工厂方法)中实现的,并且使用该值的代码可以依靠类型检查器来知道验证已经发生。

  

如果我这样检查if(numberOfHours> MaxWorkDayHours)是否应该抛出异常,说numberOfHours达到限制或返回null?

这取决于。还有另一种选择,就是返回一个or类型。工厂将返回对象或验证错误列表。

返回null是我的最后选择-这对我的品味有点隐含;我希望通过返回一个集合使从该方法返回0或1个对象的事实变得明确。例如,请参见Optional

返回可能包含验证错误列表的or类型与抛出包含验证错误列表的异常基本上是双重的。异常使您可以更轻松地将异常处理与快乐路径分开,但这既有好处也有成本。

  

请问您返回一个or类型是什么意思?

“或”类型是一种将保留一种类型或另一种类型的值的类型。

Or<Left,Right>

在模式匹配是头等大事的语言中,您将使用switch语句“解压缩”类型。在没有这些构造的语言中,通常通过传递一对回调来完成工作

Or<Left,Right> thing = ...
thing.execute( onLeft , onRight )

Execute将调用onLeft(Left x)onRight(Right x),具体取决于内部设置的值。

一个穷人的OrType看起来像是一个有两个成员的Type,其中至少一个成员总是null

答案 1 :(得分:1)

我建议您执行以下操作:

public class Worktime
{
    int _maxWork;
    int _workHours;

    public Worktime(int maxWork)
    {
        _maxWork = maxWork;
    }

    public int NumberOfWorkHours
    {
        get { return _workHours; }
        set
        {
            if (value > _maxWork)
                throw new ArgumentOutOfRangeException("Work hours should not exceed " + _maxWork);

            _workHours = value;
        }
    }
}

然后,域层应捕获异常并处理通知用户,我更希望工厂应始终返回有效实例,而不是null值,除非抛出异常以明确地知道问题,而不仅仅是返回null实例而不知道是什么问题。

希望这会有所帮助。

答案 2 :(得分:0)

  1.   

    可以检查特定字段的值不能大于a
          具体号码?或这种类型的验证应在模型中       MVC不在域层中?还是两者皆有?

    从我的观点来看,我认为您可以在创建WorkTime对象的地方检查它比从模型检查它更好(在这种情况下,它在您的Create()方法内部)。

    让我们想一想:如果将来有另一个团队成员使用您的Create()方法,而他不知道此验证,他将不会在意。 =>在这里点一下即可帮助您解决这一风险点。

    此外,将来,也许您会在许多地方使用Create(),并且如果您从Create()方法中进行验证,则需要一次又一次地对其进行验证,并制作一个重复的代码。

  

如果我这样检查if(numberOfHours> MaxWorkDayHours)是否应该抛出异常,说numberOfHours达到限制或返回null?

这取决于您如何处理结果。如果需要向用户显示一些详细信息,则需要引发异常,并将其捕获到某个地方以向用户显示问题信息。否则,您可以选择更简单的解决方案:返回null。

问候!