Получить результат выполненного метода в Command Pattern - PullRequest
11 голосов
/ 14 января 2012

В настоящее время я пытаюсь реализовать шаблон сценария транзакции (точно, как Мартин Фаулер описал с использованием Шаблон команды ) в простом тестовом проекте, все просто отлично работает, проблема в том, где я не знаю, как получить результат (ы), когда указанный метод выполняется в конкретном классе, который унаследован от интерфейса ICommand.

Давайте покажем вам код, чтобы уточнить, какие функции у меня есть. У меня есть простой класс CalculateSalaryCommand, унаследованный от интерфейса ICommand

public class CalculateSalaryCommand : ICommand
{
    private readonly CalculateSalaryTS _salaryTs;
    private readonly int _hour;
    private readonly int _salaryPerHour;

    public CalculateSalaryCommand(CalculateSalaryTS salaryTs, int hour, int salaryPerHour)
    {
        _salaryTs = salaryTs;
        _hour = hour;
        _salaryPerHour = salaryPerHour;
    }

    public void Execute()
    {
        _salaryTs.CalculateSalary(_hour, _salaryPerHour);
    }
}

и простой класс сценария транзакции с именем CalculateSalaryTS

public class CalculateSalaryTS {
    public void CalculateSalary(int _hour, int _salaryPerHour) {
        Result = _hour * _salaryPerHour;
    }
}

как видите, я передаю экземпляр класса конкретной команде, а затем внутри метода Execute выполняю операции из этого экземпляра. Ну, все просто хорошо выглядит. но есть проблема, я не могу вернуть результат выполненного метода, который должен быть целым числом. Чтобы решить эту проблему, я решил добавить некоторый код на уровень сценария транзакции, который каждая транзакция должна наследовать от общего интерфейса ITransactionResult, который выглядит следующим образом:

public interface ITransactionResult<TResult>
{
    TResult Result { get; set; }
}

Тогда класс CalculateSalaryTS стал таким:

public class CalculateSalaryTS : ITransactionResult<Int32> {

    public void CalculateSalary(int _hour, int _salaryPerHour) {
        Result = _hour * _salaryPerHour;
    }

    public int Result { get; set; }

}

Использование:

    var script = new CalculateSalaryTS();
    var command = new CalculateSalaryCommand(script, 10, 20);           
    command.Execute();
    Console.WriteLine("Salary is {0}", script.Result);

Я знаю, что у этого способа есть свои ограничения, но у меня нет выбора, пока вы не дадите мне другую идею для разрешения этой ситуации.

Заранее спасибо.

Ответы [ 2 ]

22 голосов
/ 14 января 2012

Если вам абсолютно необходимо получить результат сразу после выполнения команды, вы можете сохранить результат в объекте команды:

public interface ICommandWithResult<T> : ICommand
{
  T Result { get; }
}

public class CalculateSalaryCommand : ICommandWithResult<int>
{
  public int Result { get; private set; }

  // ...

  public void Execute()
  {
    _salaryTs.CalculateSalary(_hour, _salaryPerHour);
    this.Result = _salaryTs.Result;
  }
}

// Usage:

var command = new CalculateSalaryCommand(new CalculateSalaryTS(), 10, 20);
command.Execute();
Console.WriteLine("Salary is {0}", command.Result);
6 голосов
/ 14 января 2012

Я думаю, что вы ищете шаблон команды, способный вернуть результат.

так

    interface ICommand<TResult>
    {
       TResult Execute();
    }


public class CalculateSalaryCommand : ICommand<int>
{
    private readonly CalculateSalaryTS _salaryTs;
    private readonly int _hour;
    private readonly int _salaryPerHour;

    public CalculateSalaryCommand(CalculateSalaryTS salaryTs, int hour, int salaryPerHour)
    {
        _salaryTs = salaryTs;
        _hour = hour;
        _salaryPerHour = salaryPerHour;
    }

    public int Execute()
    {
        return _salaryTs.CalculateSalary(_hour, _salaryPerHour);
    }
}
...