質問

Currently I'm trying to implement Transaction Script pattern (Exactly how Martin Fowler described by using Command Pattern) in a simple test project, everything just work fine, the problem is where I don't know how to get result(s) when specified method executed in concrete class which is inherited from ICommand interface.

Let's show you some code to clarify what functionality I have. I've a simple CalculateSalaryCommand class which inherited from ICommand interface

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

and a simple Transaction Script class named CalculateSalaryTS

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

as you can see I pass the instance of to concrete command class, then inside the Execute method I execute a operations from that instance. Well, everything just look good. but there is a problem I can't return the result of executed method which is should be a integer. To handle this problem, I decided to add some code to Transaction Script layer which each transaction should inherit from a generic ITransactionResult interface, which is look like following:

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

Then CalculateSalaryTS class became like this :

public class CalculateSalaryTS : ITransactionResult<Int32> {

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

    public int Result { get; set; }

}

Usage :

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

I know this way has its own limitation but I don't have any choice till you give me another idea to handle this situation.

Thanks in advance.

役に立ちましたか?

解決

If you absolutely need to get the result immediately after command execution, you could store the result in the command object:

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

他のヒント

I think you are looking for a command pattern which is capable of returning result.

so,

    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);
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top