class CalculationResult<T>
{
public static CalculationResult<T> Success(T result)
{
return new CalculationResult<T>
{
IsSuccess = true,
Result = result
};
}
public static CalculationResult<T> Failure(Exception error)
{
return new CalculationResult<T>
{
IsSuccess = false,
Error = error
};
}
public bool IsSuccess { get; private set; }
public Exception Error { get; private set; }
public T Result { get; private set; }
}
Класс CalculationResult<T> использует инкапсуляцию, чтобы задать контракт:
IsSuccess == true, то Result задан, вычисление завершилось без исключенийIsSuccess == false, то Result не задан, вычисление завершилось с исключениемПользователь этого класса не имеет возможность изменить его поведение и нарушить консистентность данных.
По code-style на работе я не могу использовать инкапсуляцию. Данные и методы, с ними работающие, должны быть строго разделены. Поэтому фабричные методы выделяются в отдельный интерфейс:
interface ICalculationResultBuilder
{
CalculationResult<T> Success<T>(T result);
CalculationResult<T> Failure<T>(Exception error);
}
При этом все private set; я вынужден заменить по крайней мере на internal set;. Это чревато тем, что теперь пользователь класса может проигнорировать ICalculationResultBuilder и сделать так:
new CalculationResult<int>
{
IsSuccess = true,
Error = new Exception(),
Result = 42
};
Подскажите другие средства языка и способы гарантированно ограничить пользователя в способах прострелить себе ногу?
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости