I have decided to split my application into 3 separate modules - one "abstract" with almost all application logic (anyone looking at the code can tell WHAT it does), one "implementation" module with all specific implementation layers (like db, connections, etc) and one small "runtime" module that maps implementation with abstraction (configures factories etc) and starts the app.
So I have an abstract PortListener class that can handle specific messages recevied from port. Most of the logic is done in this class, only specific implementation details (like port opening, closing, reading bytes from port and converting it to domain message) are moved to the PortListenerImplementation. PortListener have abstract methods called "listen()" - it should open port and add itself as a listener to the port, and "close()" - remove listener, close port. And there is method called "handleMessage(Message message)" that handles messages and do whatever it is needed.
How to obligate PortListenerImplementation to call "handleMessage()" in its own "real" listener method? Is there something like Reversed Template Method? Or maybe I've just gone too far? :D
Thx
PortListener is an abstract class. Methods listen(), close(), readMessage(), sendMessage() are abstract and should be implemented in the child class. Those methods should create low level operations like opening connection or reading bytes from port. I do not want to mix that kind of details in my base class - I want only business logic there - method onMessageReceived() it is my business logic. It creates specific response, save data to database, change other objects etc.
PortListenerImp is a concrete class. It implements all needed methods. I would love to "force" PortListenerImp to use a parent's onMessageReceived() whenever a new message is received.
I think there is no easy way of doing it without going to specific details of SerialPortListener in abstract PortListener class. What I have managed is to make it more obvious what method should be called in the implementation class. I have added Event parameter to the PortListener class and added onEvent() method. Also method readMessage should ask for the Event object. So with this design it is more clear that PortListenerImp should use onEvent as an event handler:
Please comment what you think about this design. Source code was minimized just to make it more clear.