Результат (шаблон проєктування)

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

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");
    }
}

Див. також[ред. | ред. код]

Джерела[ред. | ред. код]