How to validate a factory method (The construction of object).
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
not in the domain layer ? or in both ?if (numberOfHours > MaxWorkDayHours)
Should I throw an exception say that numberOfHours reach the limit
or return null ?Is it okay to check that a specific field can't be greater than a specific number ?
Yes - that's a normal thing to do when we are using domain agnostic types (like bytes) to express some domain specific concept.
this type of validation should be in the model of MVC not in the domain layer ?
Domain layer for sure; but it may also make sense to do it in the model. The motivation for checking value constraints in the model is that you want to limit the number of different places in the code that the check needs to be.
It's a common pattern in domain-driven-design to introduce a Value Object
that represents the domain concept; the check is implemented in the constructor (or factory method) that creates the value, and code that uses the value can rely on the type checker to know that validation has already happened.
If I make a check like this if (numberOfHours > MaxWorkDayHours) Should I throw an exception say that numberOfHours reach the limit or return null ?
It depends. There is another alternative as well, which is to return an or-type; the factory returns either the object or a list of validation errors.
Returning null would be my last choice - it is a bit implicit for my taste; I would rather that the fact that you return 0 or 1 objects from the method be made explicit by returning a collection. See Optional, for example.
Returning an or-type that might include a list of validation errors is basically dual to throwing an exception that includes a list of validation errors. Exceptions allow you to more easily separate exception handling from the happy path, but that has benefits and costs.
Could I ask What did u mean by return an or-type ?
An Or type is a type that will either hold a value of one type or of another type.
Or<Left,Right>
In languages where pattern matching is a first class concern, you would use a switch statement to "unpack" the type. In languages where you don't have those constructions, you often do work by passing a pair of callbacks
Or<Left,Right> thing = ...
thing.execute( onLeft , onRight )
Execute will call either onLeft(Left x)
or onRight(Right x)
, depending on which value has been set internally.
A poor man's OrType might look like a Type with two members, at least one of which is always null