jeudi 10 août 2017

Command Pattern with Undo , returning response in Invoker and Command class or Callback?

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