Результат (шаблон проєктування)
Зовнішній вигляд
Result — шаблон проєктування функційного програмування.
- Функція є чистою так, як прототип описує усю поведінку.
- Дозволяє реалізувати спільний варіант обробки помилок.
Нехай, необхідно реалізувати функціонал зняття готівки із рахунку. Наївна реалізація може мати такий вигляд:
public class BankAccount
{
public decimal Balance { get; private set; }
public bool Withdraw(decimal amount)
{
if (amount < 0)
{
throw new ArgumentOutOfRangeException(nameof(amount));
}
if (IsAccountFrozen())
{
return false;
}
if (Balance - amount >= 0)
{
Balance -= amount;
return true;
}
return false;
}
}
Така реалізація погана із декількох причин:
- прототип методу приховує побічні ефекти (такі як винятки)
- тип повернення (false) не повідомляє про причину помилки
Введемо додатковий тип, який буде виражати результат операції
public class Result
{
public bool IsSuccessful { get; private set; }
public string Error { get; private set; }
public static Result Success()
{
return new Result
{
IsSuccessful = true,
Error = "",
};
}
public static Result Failure(string error)
{
return new Result
{
IsSuccessful = false,
Error = error,
};
}
}
Та змінимо реалізацію методу використовуючи новий тип:
public class BankAccount
{
public decimal Balance { get; private set; }
public Result Withdraw(decimal amount)
{
if (amount < 0)
{
return Result.Failure("Amount can not be less than zeno");
}
if (IsAccountFrozen())
{
return Result.Failure("Account is frozen");
}
if (Balance - amount >= 0)
{
Balance -= amount;
return Result.Success();
}
return Result.Failure("Account has insufficient funds");
}
}