如何设计抽象监听器及其实现?
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
}
}
请评论您对此设计的看法。源代码被最小化只是为了让它更清晰。
我决定将我的应用程序分成 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
}
}
请评论您对此设计的看法。源代码被最小化只是为了让它更清晰。