Project description:
I have a nodejs project where I try to build a bluetooth mesh like network, each node consists roughly of 4 parts the frontend part, the message broker, a bluetooth client and a bluetooth server.
The message broker creates the bluetooth server, client and all the dependencies and runs in its own node process, also the bluetooth server and client run in there own nodejs process (The server and client write large payloads directly to the disc and do some converting and compression/decompression in there threads).
This message broker has to handle messages from the frontend process (requests to do something from the user) and the bluetooth client (central) or the bluetooth server (peripheral) (requests from another node). Messages from the server and client will be delegated to specific message handlers frontend messages are handled by the broker himself.
These are my message broker related classes:
Where is the problem:
MessageBroker
creates:
BluetoothClient
,
BluetoothServer
,
MetaDataManager
(just an object to share necessary data between the broker, client and server, but it got very ugly by now there are multiple arrays to keep track of pending actions and past requests),
BluetoothStateController
(keeps track of the blutooth adapter state so that the broker, client or server can check whether bluetooth is active and if so whether its scanning/advertising/connected)
BluetoothClientMessageHandler
(the message boker passes all messages from the bluetooth client to this class, depending on the state, meta data and the received message a action is performed e.g. connect -> read data -> write data. All of this is async so the response for the connect, read and wirte action arrives all in the entry method of the handler from which it is delegated to another method)
BluetoothServerMessageHandler
(Similar to the client)
What is the problem: The handlers are each around 300 lines of code with lots of conditionals (if else and switch case)(the messages are JSON objects from the other node processes) and so far I have failed to split them into smaller classes because there methods are too tightly coupled, the message handlers are however handling a wide range of messages (diffrent types) so the first thing that I thought of was to split them into message handler classes for (error messages, onDiscover messages, onConnect messages, readCompleted messages ....).
Also I know that the word "handler" means that these classes are probably to broad and do not conform to the single responsibility principle. The open close principle is probably also violated because of the switch case statements within the message handlers.
Solution Attempt:
When I split them up, in contrary to what I would expect they each need the same number of dependencies (e.g. the MetaDataManager), that does not look like a good solution to me. The broker would need to create even more message handlers (so yes the message handlers get smaller but the message broker gets crowded now) and the MetaDataManager might need to keep track of even more shared data.
UPDATE: I rethought my solution attempt and figured it might not be so bad if I use something like a Facade Service as mentioned in this question to wrap the dependencies e.g. I would split the message handlers into specific message handlers, create shared dependencies in another class to hold the dependencies and another one to create all the message handlers, the message broker then only creates an instance of the class creating all the shared dependencies and passes this object to the object wrapping all the message handlers.
Does someone see a better way to decouple these classes ?