I have a `Shift` class that looks like this: public class Shift { public string Name { get; private set; } public TimeSpan StartHour { get; private set; } public TimeSpan EndHour { get; private set; } public TimeSpan Duration => EndHour - StartHour; private Shift(string name, TimeSpan startHour, TimeSpan endHour) { Name = name; StartHour = startHour; EndHour = endHour; } private Shift() { } } Since there are some limitations and restrictions to what `StartHour` && `EndHour` can be I needed some way to validate the input of the class and if it fails - prevent the creation of the object or at least not return it to the user, without throwing an exception because I want to allow the user to re-enter the arguments if some of them were invalid. Than I created an interface and some derived classes to be injected during the construction of the object: public interface IShiftValidator { Exception FailedValidationException { get; } string FailedValidationMessage { get; } bool IsValid(Shift shiftToValidate); } public class ShiftRangeValidator : IShiftValidator { public Exception FailedValidationException { get; private set; } public string FailedValidationMessage { get; private set; } = string.Empty; public bool IsValid(Shift shiftToValidate) { if (shiftToValidate.Duration.TotalMinutes <= 0) { FailedValidationException = new ArgumentOutOfRangeException(nameof(shiftToValidate.Duration)); FailedValidationMessage = "Shift's duration cant be less than 1 minute."; return false; } if (shiftToValidate.Duration.TotalHours > SharedSettings.MaximumShiftHours) { FailedValidationException = new ArgumentOutOfRangeException(nameof(shiftToValidate.Duration)); FailedValidationMessage = "Shift's duration cant be longer than the maximum allowed hours."; return false; } return true; } } After that I implemented the builder pattern as a nested class in the `Shift` class, so I can make the constructor of the class private and construct the object fully in the builder class: public class ShiftBuilder { private Shift _shift; public ShiftBuilder() { _shift = new Shift(); } public ShiftBuilder WithName(string name) { _shift.Name = name; return this; } public ShiftBuilder WithStartHour(TimeSpan startHour) { _shift.StartHour = startHour; return this; } public ShiftBuilder WithEndHour(TimeSpan endHour) { _shift.EndHour = endHour; return this; } public Shift Build(IEnumerable<IShiftValidator> validators) { if (validators != null) { foreach (var shiftValidator in validators) { if (!shiftValidator.IsValid(_shift)) { if (!string.IsNullOrEmpty(shiftValidator.FailedValidationMessage)) { MessageBox.Show(shiftValidator.FailedValidationMessage); } throw shiftValidator.FailedValidationException; } } } Shift shift = _shift; _shift = null; return shift; } } Here's an example usage: Shift.ShiftBuilder shiftBuilder = new Shift.ShiftBuilder(); var a = shiftBuilder.WithName("Test") .WithStartHour(new TimeSpan(12, 0, 0)) .WithEndHour(new TimeSpan(24, 0, 0)) .Build(new[] { new ShiftRangeValidator() }); var b = shiftBuilder.Build(null); // null var c = shiftBuilder.Build(new[] {new ShiftRangeValidator()}); // crash I have few concerns: 1. Is it clear that you're unable to reuse the same `ShiftBuilder` twice? 2. Is `IShiftValidator` good as it is or should I separate it in few smaller interfaces?