0

我决定将我的应用程序分成 3 个单独的模块 - 一个包含几乎所有应用程序逻辑的“抽象”(任何查看代码的人都可以知道它做了什么),一个包含所有特定实现层(如数据库、连接、等)和一个小的“运行时”模块,它用抽象映射实现(配置工厂等)并启动应用程序。

所以我有一个抽象的 PortListener 类,可以处理从端口接收到的特定消息。大部分逻辑都在这个类中完成,只有特定的实现细节(如端口打开、关闭、从端口读取字节并将其转换为域消息)被移动到 PortListenerImplementation。PortListener 具有称为“listen()”的抽象方法——它应该打开端口并将自己作为监听器添加到端口,以及“close()”——删除监听器,关闭端口。还有一种名为“handleMessage(Message message)”的方法可以处理消息并做任何需要的事情。

如何强制 PortListenerImplementation 在其自己的“真实”侦听器方法中调用“handleMessage()”?有没有类似反向模板方法的东西?还是我走得太远了?:D

谢谢

4

1 回答 1

0

图表

PortListener 是一个抽象类。方法 listen()、close()、readMessage()、sendMessage() 是抽象的,应该在子类中实现。这些方法应该创建低级操作,例如打开连接或从端口读取字节。我不想在我的基类中混合那种细节——我只想要那里的业务逻辑——方法 onMessageReceived() 这是我的业务逻辑。它创建特定的响应,将数据保存到数据库,更改其他对象等。

PortListenerImp 是一个具体的类。它实现了所有需要的方法。每当收到新消息时,我很想“强制” PortListenerImp 使用父母的 onMessageReceived() 。

我认为如果不了解抽象 PortListener 类中 SerialPortListener 的具体细节,就没有简单的方法。我所做的就是让实现类中应该调用什么方法更加明显。我已将 Event 参数添加到 PortListener 类并添加了 onEvent() 方法。方法 readMessage 也应该询问 Event 对象。因此,通过这种设计,更清楚的是 PortListenerImp 应该使用 onEvent 作为事件处理程序:

public abstract class PortListener<Event> {

    private final String portName;

    public abstract void listen();

    public abstract void close();

    abstract Message readMessage(Event event);

    abstract void sendMessage(Message message);

    public final void onEvent(Event event) {
        Message message = readMessage(event);
        onMessageReceived(message);
    }

    private void onMessageReceived(Message message) {
        // some business logic here
    }
}

public class SerialPortListener extends PortListener<SerialPortEvent> {

    private final SerialPort serialPort;

    @Override
    public void listen() {
        if(!tryToOpenPortAndSetParameters())
            throw new PortOpenException(getPortName());

        tryToAddListener();
    }

    private boolean tryToOpenPortAndSetParameters() {
        // return tryToOpenPort() && setPortParameters();
    }

    @Override
    public void close() {
        if(!tryToRemoveListenerAndClosePort())
            throw new PortCloseException(getPortName());
    }

    private boolean tryToRemoveListenerAndClosePort() {
        // return tryToRemoveListener() && tryToClosePort();
    }

    @Override
    void sendMessage(Message message) {
        // send messsage
    }

    @Override
    Message readMessage(SerialPortEvent serialPortEvent) {
        if (serialPortEvent.getEventValue() > 0)
            return tryToReadMessage();

        return Message.EMPTY;
    }

    private void tryToAddListener() {
        try {
            serialPort.addEventListener(this::onEvent);
        } catch (SerialPortException e) {
            throw new PortOpenException(getPortName(), e.getMessage());
        }
    }

    private Message tryToReadMessage() {
        // read message
    }
}

请评论您对此设计的看法。源代码被最小化只是为了使其更清晰。

于 2015-06-12T07:26:34.743 回答