I have used command pattern with undo support, The terms associated with Command Pattern are as follows
Client -> Invoker -> Command instance execute() -> Receiver
so the client will need to know whether the operation was successfully so that it can decide whether to undo .
in my example Receiver talks to the Volt DB using some APIs, so there a predefined response classes with result code and result message.
It would be bad if i sent those all the way to the client.
Having Invoker and Command to return boolean indicating success or failure feels better. I have seen a example where they use callbacks - http://ift.tt/2wNF9Vh . Is this something only for asynch operations or I can also use it here, which would be better? Snippets of the code are below , full code are in http://ift.tt/2vUCBIy.
Invoker class
package com.spakai.undoredo;
import java.util.Stack;
public class Invoker {
private final Stack<Command> undoStack;
private final Stack<Command> redoStack;
public Invoker() {
undoStack = new Stack<>();
redoStack = new Stack<>();
}
public void execute(Command cmd) {
undoStack.push(cmd);
redoStack.clear();
cmd.execute();
}
public void undo() {
if (!undoStack.isEmpty()) {
Command cmd = undoStack.pop();
cmd.undo();
redoStack.push(cmd);
}
}
public void redo() {
Command cmd = redoStack.pop();
cmd.execute();
undoStack.push(cmd);
}
}
Receiver interface
package com.spakai.undoredo;
public interface Receiver {
public CreateGroupResponse createGroup(int groupId, int subscriptionId);
public DeleteGroupResponse deleteGroup(int groupId);
//many more
}
Command interface
package com.spakai.undoredo;
public interface Command {
public void execute();
public void undo();
public void redo();
}
Sample Command instance
package com.spakai.undoredo;
public class CreateGroupAndSubscription implements Command {
// which states do i need to store in order to execute and undo
private int groupId;
private int subscriptionId;
// this is the Volt handle apis that talks to VoltDB
private Receiver receiver;
public CreateGroupAndSubscription(int groupId, int subscriptionId, Receiver receiver) {
this.groupId = groupId;
this.subscriptionId = subscriptionId;
this.receiver = receiver;
}
@Override
public void execute() {
CreateGroupResponse response = receiver.createGroup(groupId,subscriptionId);
}
@Override
public void undo() {
DeleteGroupResponse response = receiver.deleteGroup(groupId);
}
@Override
public void redo() {
execute();
}
}
Any other suggestions on the whole code are most welcomed.
Aucun commentaire:
Enregistrer un commentaire