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.
An Invoker class contains a reference to a Command and has a method to execute the Command. In the command pattern, the invoker is decoupled from the action performed by the receiver. The invoker has no knowledge of the receiver.
In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to encapsulate all information needed to perform an action or trigger an event at a later time. This information includes the method name, the object that owns the method and values for the method parameters.
A Command pattern is an object behavioral pattern that allows us to achieve complete decoupling between the sender and the receiver. (A sender is an object that invokes an operation, and a receiver is an object that receives the request to execute a certain operation.
The command pattern should be used when: You need a command to have a life span independent of the original request, or if you want to queue, specify and execute requests at different times. You need undo/redo operations. The command's execution can be stored for reversing its effects.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With