1

如何创建一个类来捕获具有不同参数类型的命令?要捕获具有类似参数类型的命令以通过摆动来操作门对象,例如(Swing, DoorNo, swingAngle),我将创建一个如下的类;

class DoorCommand {
     private String commandName;
     private int doorNo;
     private float swingAngle;

     public DoorCommand (String cmdName, int doorNo, float swing angle) {
        // set values here
     }

     // do all the setter and getter here
}

(Lock, ENABLE/DISABLE)我的问题是,我需要使用as 参数来启用和禁用门锁。我如何在DoorCommand课堂上适应这种情况?我希望能够将 DoorCommands 存储在列表中;List<DoorCommand> doorCommands = new ArrayList<DoorCommand>();

4

5 回答 5

2

你为什么不提取门命令的接口,比如说IDoorCommand

然后DoorCommand从您的示例中实现它(实际上我会将名称更改为更相关,例如SwingDoorCommand)。

然后添加另一个命令,实现IDoorCommand,说DoorLockControlCommand关闭/打开锁,具体取决于构造函数参数。

通过这种方式,您将能够存储两种类型的命令List<IDoorCommand>并调用它们,而无需知道命令是否执行的详细信息。

希望这能回答你的问题。

于 2013-07-31T11:01:46.453 回答
1

您可能想查看命令模式,它允许您将每个命令创建为通用接口的子类,因此将命令存储在列表中以用于历史或撤消目的。在你的情况下:

// The basic interface for all door commands
public interface DoorCommand {
    public void execute(Door door) throws CommandException;
}

// The Door class is the recipient for all commands
public class Door {
    private List<Command> history = new ArrayList<Command>();
    private int angle;
    private boolean locked;

    public void addCommandToHistory(Command command) {
        history.add(command);
    }

    // Getters and setters.
}

// The command to open the door
public class OpenDoor implements DoorCommand {
    public void execute(Door door) throws CommandException {
        door.addCommandToHistory(this);
        if (door.isLocked()) {
            throw new CommandException("Door is locked, cannot open");
        }
        if (door.getAngle() < 90) {
            door.setAngle(90);
        }
    }
}

// Another command, LockDoor
public class LockDoor implements DoorCommand {
    public void execute(Door door) throws CommandException {
        door.addCommandToHistory(this);
        door.setLocked(true);
    }
}

然后你可以使用这样的命令:

public void operateDoor() {
    Door door = new Door();
    new LockDoor().execute(door);
    new OpenDoor().execute(door);
}

或者,您可以Door使用构造函数将对象传递给命令。

于 2013-07-31T11:12:47.490 回答
1

我不确定我是否理解你的问题。在我看来,您的命令只是存储操作的信息,它们不是对门进行操作,例如更改门的实例变量等,对吗?如果你愿意改变这一点,你可以使用Command Pattern。也许这已经是你的计划了。然后该命令在执行时必须考虑Door' 的状态。

于 2013-07-31T11:13:17.500 回答
0

使用polymorphism使用类似的东西。

public class DoorCommand {
    private String cmdName;
    private static List<DoorCommand> list;

    static interface DoorCommandBase {
        void doAction(Object... arg);
    }

    class SwingCommand implements DoorCommandBase {
        void doAction(Object... arg) {
            int doorNo;
            float swingAngle;

            cmdName = arg[0];
            doorNo = arg[1];
            swingAngle = arg[2];
            // action to be performed
            updateList(arg);
        }
    }

    class LockCommand implements DoorCommandBase {
        void doAction(Object... arg) {
            boolean istrue;

            cmdName = arg[0];
            istrue = arg[1];
            // action to be performed
            updateList(arg);
        }
    }

    public static void updateList(Object... arg) {
        // update list
    }

    // getters and setters
}
于 2013-07-31T11:28:28.490 回答
0

使用访客模式。

您的命令有一个接受 aDoor并对其进行操作的方法。

你遍历你的DoorCommand对象并发送每个对象Door,它会做它想做的事情。

这样,您的DoorCommand逻辑与逻辑分离,Door并且您不需要一个庞大的DoorCommand类来实现所有可能的命令。

这是一个简单的例子:

static class Door {

    private final String name;

    public Door(String name) {
        this.name = name;
    }

    public void accept(final DoorVisitor visitor) {
        visitor.visit(this);
    }

    @Override
    public String toString() {
        return name;
    }
}

static interface DoorVisitor {

    void visit(Door door);
}

static class SwingCommand implements DoorVisitor {

    private final float swingAngle;

    public SwingCommand(float swingAngle) {
        this.swingAngle = swingAngle;
    }

    @Override
    public void visit(Door door) {
        System.out.printf("Swing door %s by %s%n", door, swingAngle);
    }
}

static class LockCommand implements DoorVisitor {

    private boolean locked;

    public LockCommand(boolean locked) {
        this.locked = locked;
    }

    @Override
    public void visit(Door door) {
        System.out.printf("Door %s is locked: %s%n", door, locked);
    }
}

public static void main(String[] args) throws Exception {
    final Door door = new Door("Front Door");
    final List<DoorVisitor> commands = new LinkedList<>();
    commands.add(new SwingCommand(0));
    commands.add(new LockCommand(true));
    for (final DoorVisitor c : commands) {
        door.accept(c);
    }
}
于 2013-07-31T11:15:58.313 回答