如何设计抽象监听器及其实现?

How to design abstract listener and its implementation?

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

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

如何强制 PortListenerImplementation 在它自己的 "real" 侦听器方法中调用 "handleMessage()"?是否有类似反向模板方法的东西?或者也许我走得太远了? :D

感谢

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

PortListenerImp 是具体的 class。它实现了所有需要的方法。 我很乐意 "force" PortListenerImp 在收到新消息时使用父级的 onMessageReceived()。

我认为如果不在抽象 PortListener class 中了解 SerialPortListener 的具体细节,就没有简单的方法可以做到这一点。我所做的是使在实现中应该调用什么方法变得更加明显 class。我已将 Event 参数添加到 PortListener class 并添加了 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
    }
}

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