mardi 12 mai 2015

What pattern(s) and techniques can I use to create a reusable command system in C#?

Scenario:

I wish to develop a client/server application with a GUI based client (e.g. WinForms or WPF) and a Windows Service based server communicating with each other most likely via TCP/IP.

The client will execute commands to edit a document on the client, and then tell the server that it has made those changes, the server may then perform it's own actions, such as informing other clients of the change.

The problem:

I intend to make use of the command pattern, so that things like undo can easily be supported. What I would like however, is to be able to maximise class reuse, and therefore allow the same command class to be used on the client, as on the server. The problem I have is that some actions carried out on executing a command class may be irrelevant to the server or client being only applicable to one or the other.

So imagine for simplicity's sake the application is a simple network enabled text editor like notepad and includes a fancy feature to reverse the entire string of text in the document. The client will invoke the command, the command will modify the text as stored in memory, it will send the command to the server, the server will tell it everything is received okay, and then the client will tell the UI to update to show the now reversed text. The server on receiving the command also updates it's internal representation of the text to reverse it, but it has no UI to update. It does however wish to tell another user that it also has to make this update. Much of the code is shared, but the UI update part, and the informing the other client part are irrelevant to the server and client respectively.

My example is intentionally simple and contrived, so I'm not worried about issues of synchronisation, network serialisation and so forth, simply the best way in which I can go about implementing a command pattern based setup whose core work of acting on an internal model on execution of a command is shared and can be passed freely between client and server, but whose actions before and after acting will be specific to the executing application.

I would like to avoid creating server and client specific versions of each command, and would like to retain the ability to send the command object across the network as is without having to map between a client and server specific version. I guess I effectively require that instantiation of each command automatically discover if there is, say, a related UpdateUI, or UpdateNetwork delegate it must call with minimal performance overhead in doing so. What is the best way to handle this?

Any thoughts or suggestions (even alternative approaches altogether!) much appreciated.

Aucun commentaire:

Enregistrer un commentaire