My question is related to the command pattern, where we have the following abstraction (C# code) :
public interface ICommand
{
void Execute();
}
<
My implementation would be this (using the ICommand proposed by Juanma):
public class DeletePersonCommand: ICommand<Person>
{
public DeletePersonCommand(IPersonService personService)
{
this.personService = personService;
}
public void Execute(Person person)
{
this.personService.DeletePerson(person);
}
}
IPersonService could be an IPersonRepository, it depends in what "layer" your command is.
Based on the pattern in C#/WPF the ICommand Interface (System.Windows.Input.ICommand) is defined to take an object as a parameter on the Execute, as well as the CanExecute method.
interface ICommand
{
bool CanExecute(object parameter);
void Execute(object parameter);
}
This allows you to define your command as a static public field which is an instance of your custom command object that implements ICommand.
public static ICommand DeleteCommand = new DeleteCommandInstance();
In this way the relevant object, in your case a person, is passed in when execute is called. The Execute method can then cast the object and call the Delete() method.
public void Execute(object parameter)
{
person target = (person)parameter;
target.Delete();
}
Have "Person" implement some sort of IDeletable interface, then make the command take whatever base class or interface your entities use. That way, you can make a DeleteCommand, which tries to cast the entity to an IDeletable, and if that works, call .Delete
public class DeleteCommand : ICommand
{
public void Execute(Entity entity)
{
IDeletable del = entity as IDeletable;
if (del != null) del.Delete();
}
}
Pass the person when you create the command object:
ICommand command = new DeletePersonCommand(person);
so that when you execute the command, it already knows everything that it needs to know.
class DeletePersonCommand : ICommand
{
private Person person;
public DeletePersonCommand(Person person)
{
this.person = person;
}
public void Execute()
{
RealDelete(person);
}
}
Already mentioned code from Blair Conrad(don't know how to tag him) works perfectly fine if you know what person you want to delete when you instantiate the class and his method would suffice.But,if you don't know who you gonna delete until you press the button you can instantiate the command using a method reference that returns the person.
class DeletePersonCommand implements ICommand
{
private Supplier<Person> personSupplier;
public DeletePersonCommand(Supplier<Person> personSupplier)
{
this.personSupplier = personSupplier;
}
public void Execute()
{
personSupplier.get().delete();
}
}
That way when the command is executed the supplier fetches the person you want to delete,doing so at the point of execution. Up until that time the command had no information of who to delete.
Usefull link on the supplier.
NOTE:code writen in java . Someone with c# knowledge can tune that.
In this case, what we've done with our Command objects is to create a Context object which is essentially a map. The map contains name value pairs where the keys are constants and the values are parameters that are used by the Command implementations. Especially useful if you have a Chain of Commands where later commands depend on context changes from earlier commands.
So the actual method becomes
void execute(Context ctx);