Serial communication design pattern
I'm currently assigned to a task to develop a software module to communicate with a stepper motor controller. The project is written in C#, I have a C++ dll to communicate with the controller. The communication runs via the Serial port. I'm planning to write the whole piece in C# by importing the necessary methods by DllImport. The key method looks something like :
ComSendReceive(pHandle, bufferIn,sizeBufferIn,bufferOut,ref bufferOut)
There are several types of messages :
- You send message and expect confirmation (not the same for every message, sometimes it's OK, sometimes it's COMPLETE etc..
- You send message and receive message - you can receive an error or data (for instance GET_CONTROLLER_ID)
- Several other types
Of course I need to control the communication for time-outs.
My question is: Is there any "de开发者_如何转开发sign pattern" to use for that kind of problem? I'm sure this is quite a common problem many developers have solved already.
To contribute a little - I dealt with similar problem in my last job and I solved it this way :
I had a class to communicate with the Com port and a class AT_message with bunch of overloaded constructors :
class AT_Message
{
public bool DoResponseCheck;
public string ExpectedResponse;
public AT_COMMAND command;
public string data;
public bool AddCarriageReturn;
...
//Plenty of ctors
}
class UnfriendlyInterface
{
Response SendMessage(AT_Message msg)
{
//Communicates directly with C++ dll, send message, check timeouts etc....
}
}
And I had a class the main application was communicating with, it had human friendly methods like
class FriendlyInterface
{
bool AutodetectPortAndOpenComm();
Result AnalyzeSignal(byte[] buffer)
{
Response response = UnfriendlyInterface.SendMessage(new Message(AT_Command.PrepareForSignal, (doResponseCheck)true, ExpectedResponse.Ok,Timeout.short);
Response response = UnfriendlyInterface.SendMessage(new Message(buffer,(doResponseCheck)false,Timeout.long);
//.... Other steps
}
//... other methods
}
Since last time I was really in a big hurry, I implemented first solution that came to my mind. But is there a way to do it better? Now the device I'm communicate with is more complex than the previous one so if there's a way how to do it better, I'd like to do it that way.
This seems like a textbook facade pattern. The answer to all of this is to encapsulate your variation. For example, try to create a generic interface for commands that give an acknowledgement, and write client code to use that interface. Then concrete types can decide how to interpret various acknowledgements into a uniform signal (Ok = Complete = Good, or whatever)
Here's a good article on the facade pattern. Also see the wikipedia article.
精彩评论