Click here to Skip to main content
15,867,942 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have Mono/C# socket server that accepts several different types of clients.

When client connects and sends data, a client factory is used to create new client of right type. The basic type is determined from the data client sends. This is the easy part - I have IClient interface that each BaseClient class inherits and data is processed in the base type clients 'HandleData' function.

Problem is, some of these base clients has several subtypes that should handle incoming data differently than the base client class. In addition, some of the client can have extra functionality (or several!) enabled that changes what data is expected and how it should be handled.

So my question is: Should I change this whole thing to use single base client class with decorator pattern handling all the different kind of data handling? Or is some other pattern better fit for my problem?

What I have tried:

Currently those base client classes that have several subtypes have internal variable called 'ClientDataHandler' that is a class doing the real data processing. 'ClientDataHandler' is of type abstract 'ClientDataHandlerBase', which is inherited by all the different client subclasses doing the real data processing inside base client class.

Maybe this makes things clearer:
1. Client connects to socket server and sends data
2. ClientFactory creates right base client according to the data
3. Socket server calls clients 'HandleData'
4. Client (HandleData) determines the subtype and instantiates 'ClientDataHandler' accordingly
5. Client (HandleData) calls 'ClientDataHandler.HandleData'

This whole thing is a mess mainly because several of the base client types can have similar functionalities (e.g parse GPRMC). Similarly many of the client subtypes can have same extension activated, which has resulted a lot of duplicate code between different 'ClientDataHandler' implementations :(
Posted
Updated 9-Jun-17 20:18pm

1 solution

When we say, client sends data in 1 above, what is the format of the data ? If it is serialized stream of bytes, how will the server determine on which exact concrete type it should initialized for the respective data stream ? This actually makes the things more complicated.

If possible, let's have a common header part in the data itself, which describes the client type. Then, inside the method HandleData(), we should have that client type passed, which will initialize the concrete type of the client, and pass the remaining data to initialize the object. Here, you can use Object pool pattern ( <a href="https://en.wikipedia.org/wiki/Object_pool_pattern")a[^] for better efficiency. Or even prototype pattern ( <a href="https://en.wikipedia.org/wiki/Prototype_pattern")a[^] may work.
 
Share this answer
 
Comments
mclang 16-Jun-17 3:06am    
Sorry, I was on business trip and forgot to check this out.

Most of the data is basic ASCII, but I think one client sends binary. We can't control the data format, so selecting the right client class to create will be a mess :(

Current logic does that, I mean creates concrete types after client type is found out. This is done using Factory/Builder class. Problem is that each client type can have additions like different IO information that need to be handled also. If I do the data handling of these additions in the concrete client types, it will results a lot of code duplication.

I will check out those two patterns.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900