实现状态模式时将键绑定应用于状态转换

发布于 11-25 16:21 字数 1018 浏览 1 评论 0原文

这是一个编程风格问题,涉及将输入键映射到实现状态模式的类中的操作的最佳策略。

我正在处理两个类:

第一个实现状态模式,它控制多状态物理设备:

class DeviceController {
    State _a, _b, _current;

    // Actions that may prompt a transition from one state to another
    public void actionA() { ... }
    public void actionB() { ... }
    public void actionC() { ... }

    public State getStateA() { ... }
    public State getStateB() { ... }

    public void setCurrentState() { ... }
};

第二个是 KeyListener,它检索所有键盘输入,并在按下的输入键与(暂时)硬编码绑定表:

class KeyDemo implements KeyListener {

    DeviceController _controller;
    ...
    @Override
    public void keyPressed(KeyEvent arg0) {
        char key = Character.toUpperCase(arg0.getKeyChar());
        switch (key) {
        case 'A':
            _controller.actionA();
            break;
        case 'B' :
        ...
    }
    ...
}

是否有最佳实践编码风格将按键绑定到控制器中的操作?我是否必须像示例代码中那样执行 switch 语句?在我看来,这个解决方案有点脏代码:状态模式不是应该消除不可维护的 if 和 switch 控制结构吗?

感谢您的建议。

here's a programming style question about the best strategy to map input keys to actions in a class that implement the state pattern.

I'm dealing with two classes:

The first implements the state pattern, which controls a multi-state physical device:

class DeviceController {
    State _a, _b, _current;

    // Actions that may prompt a transition from one state to another
    public void actionA() { ... }
    public void actionB() { ... }
    public void actionC() { ... }

    public State getStateA() { ... }
    public State getStateB() { ... }

    public void setCurrentState() { ... }
};

The second is a KeyListener that retrieves all keyboard input and calls the appropriate action from the device controller when a pressed input key matches a (for the time being) hard-coded bindings table:

class KeyDemo implements KeyListener {

    DeviceController _controller;
    ...
    @Override
    public void keyPressed(KeyEvent arg0) {
        char key = Character.toUpperCase(arg0.getKeyChar());
        switch (key) {
        case 'A':
            _controller.actionA();
            break;
        case 'B' :
        ...
    }
    ...
}

Is there a best-practice coding style to bind the keys to the actions in the controller ? Do I have to go through a switch statement, as in the sample code ? It seems to me that this solution is somewhat dirty code: isn't the state pattern supposed to eliminate unmaintanable if and switch control structures ?

Thank you for your suggenstions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笑梦风尘2024-12-02 16:21:24

使用多态性您可以实现您的目标。我已经使用了枚举,但也许使用接口或抽象类然后实现每个关键处理器会更合适。你怎么认为?

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

enum KeyProcessor {
    A {
        void executeAction() {
            _controller.actionA();
        }
    },
    B {
        void executeAction() {
            _controller.actionB();
        }
    };

    private static final DeviceController _controller = new DeviceController();

    void executeAction() {
        System.out.println("no action defined");
    }
}

class DeviceController {
    State _a;
    State _b;
    State _current;

    // Actions that may prompt a transition from one state to another
    public void actionA() {
        System.out.println("action A performed.");

    }

    public void actionB() {
        System.out.println("action B performed.");
    }

    public void actionC() {
    }

    public State getStateA() {
        return null;
    }

    public State getStateB() {
        return null;
    }

    public void setCurrentState() {
    }
} // end class DeviceController

public class KeyDemo implements KeyListener {

    DeviceController _controller;

    // ...
    @Override
    public void keyPressed(KeyEvent arg0) {
        keyPressed(Character.toUpperCase(arg0.getKeyChar()));
        // ...
    }

    public void keyPressed(char c) {
        KeyProcessor processor = KeyProcessor.valueOf(c + "");
        if (processor != null) {
        processor.executeAction();
    }

    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    public static final void main(String[] args) {
        KeyDemo main = new KeyDemo();
        main.keyPressed('A');
        main.keyPressed('B');
    }
} // end class KeyDemo

class State {
}

Using polymorphism you can achive your goal. I've used enum but maybe it would be more appropriated to use interfaces or an abstract class and then implement each of the key processors. What do you think?

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

enum KeyProcessor {
    A {
        void executeAction() {
            _controller.actionA();
        }
    },
    B {
        void executeAction() {
            _controller.actionB();
        }
    };

    private static final DeviceController _controller = new DeviceController();

    void executeAction() {
        System.out.println("no action defined");
    }
}

class DeviceController {
    State _a;
    State _b;
    State _current;

    // Actions that may prompt a transition from one state to another
    public void actionA() {
        System.out.println("action A performed.");

    }

    public void actionB() {
        System.out.println("action B performed.");
    }

    public void actionC() {
    }

    public State getStateA() {
        return null;
    }

    public State getStateB() {
        return null;
    }

    public void setCurrentState() {
    }
} // end class DeviceController

public class KeyDemo implements KeyListener {

    DeviceController _controller;

    // ...
    @Override
    public void keyPressed(KeyEvent arg0) {
        keyPressed(Character.toUpperCase(arg0.getKeyChar()));
        // ...
    }

    public void keyPressed(char c) {
        KeyProcessor processor = KeyProcessor.valueOf(c + "");
        if (processor != null) {
        processor.executeAction();
    }

    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    public static final void main(String[] args) {
        KeyDemo main = new KeyDemo();
        main.keyPressed('A');
        main.keyPressed('B');
    }
} // end class KeyDemo

class State {
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文