How to design a scriptable communication emulator?
- by Hawk
Requirement:
We need a tool that simulates a hardware device that communicates via RS232 or TCP/IP to allow us to test our main application which will communicate with the device.
Current flow:
User loads script
Parse script into commands
User runs script
Execute commands
Script / commands (simplified for discussion):
Connect RS232 = RS232ConnectCommand
Connect TCP/IP = TcpIpConnectCommand
Send data = SendCommand
Receive data = ReceiveCommand
Disconnect = DisconnectCommand
All commands implement the ICommand interface. The command runner simply executes a sequence of ICommand implementations sequentially thus ICommand must have an Execute exposure, pseudo code:
void Execute(ICommunicator context)
The Execute method takes a context argument which allows the command implementations to execute what they need to do. For instance SendCommand will call context.Send, etc.
The problem
RS232ConnectCommand and TcpIpConnectCommand needs to instantiate the context to be used by subsequent commands. How do you handle this elegantly?
Solution 1:
Change ICommand Execute method to:
ICommunicator Execute(ICommunicator context)
While it will work it seems like a code smell. All commands now need to return the context which for all commands except the connection ones will be the same context that is passed in.
Solution 2:
Create an ICommunicatorWrapper (ICommunicationBroker?) which follows the decorator pattern and decorates ICommunicator. It introduces a new exposure:
void SetCommunicator(ICommunicator communicator)
And ICommand is changed to use the wrapper:
void Execute(ICommunicationWrapper context)
Seems like a cleaner solution.
Question
Is this a good design? Am I on the right track?