12

目前我正在尝试在一个简单的测试项目中实现事务脚本模式(正是 Martin Fowler使用Command Pattern描述的方式),一切正常,问题是我不知道如何在指定时获得结果在继承自 ICommand 接口的具体类中执行的方法。

让我们给你看一些代码来阐明我有什么功能。我有一个从 ICommand 接口继承的简单 CalculateSalaryCommand 类

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

我知道这种方式有其自身的局限性,但在您给我另一个想法来处理这种情况之前,我别无选择。

提前致谢。

4

2 回答 2

27

如果您绝对需要在命令执行后立即获取结果,您可以将结果存储在命令对象中:

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);
于 2012-01-14T15:12:19.200 回答
6

我认为您正在寻找一种能够返回结果的命令模式。

所以,

    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);
    }
}
于 2012-01-14T14:48:05.837 回答