In a server side application the same piece of business logic is often activated through many different channels. Im currently working on a container shipping project, and the containers can get into our system through either
a) Regular web-interface, add a new container, edit it etc.
b) Upload of a file containing one or more containers.
c) Be retrieved from a mainframe system, over a message
There could be many more different dispatching mechanisms to the same business logic (read/insert/edit/delete containers), for instance files could be uploaded via FTP instead of HTTP. Or a web service could be listening for rich client requests.
To make the MVC fit server-side app's I suggest splitting the control domain into controls and dispatchers. Controls still control and manipulate the models and the views as before. The dispatchers only translate a request so it can be executed by a control, and nothing more. Examples of dispatching mechanisms are:
- Servlets/JSP's (translating HTTP Requests).
- JMS listeners.
- Web Services
- File watchers (looking for new files in certain directories).
- Services, running a regular intervals.
- Proprietary servers, listening for request from customers using their own protocol.
- Domain model change listeners.
MVCD is not a "new" pattern. I know many server-side developers have been doing this division of controls and dispatchers already, without thinking about it. I see MVCD merely as putting a name + pattern on what we are already doing. A name which is a bit more precise for server side app's than the old MVC pattern.
What do YOU think?? :-)
In case anyone had any doubts, I meant MVCD (MVC + D), not MCVD as the original title says :-)
Dispatch is often tightly bound to View and merely a client of the Controller.
IMHO, Controller breaks down into a kind of central command engine and a bunch of commands, task and message handlers that are delegated to by the engine. It is also a kind of facade for a set of related domains.
If we want to break it down fully, I might easily go with this:
(persistence, domain, commands, control, disptach, view)
Persistence: (DomainManagers/Persistence Handlers),
(CRUD, caching, (caching rules) for various persistent stores)
DomainModel (the model. these can float up and down the tiers as each teir handles the responsibility it has on it. The domain may have a method for each teir as well as a "state" ie: validate()/validating(), hasErrors(), getErrors(), dispatching(), processing()/preProcessA()/postProcessA(), store() )
Controller Engine (facade for the application or main business service / flow of an application)
Actions (or CommandHandlers) (command pattern modules...they are actually kind of a handler or delegate, dispatchers actually send actions)
View Dispatchers (view transition logic + client for controller + validation + formatting request into something less servlet api dependant.)
If I go by package structure, I have adaptors and utils as well. Adaptors are for making the rest of the packages independant of any external packages and to have better control on any third party dependancies/facade wrapping or extending the more frequent use stuff... I use adaptors for things like loggers, algorithms, frameworks and testing utilities. Utilities should probably go its a project neutral reuse library of packages but sometimes, you need a utility for only one project so I always have a util as well...however, those are implementation detail and not pattern functionality.
I do agree that I have seen this dispatcher concept a lot on the server side. The dispatch I consider view specific though. My Controller "engine", is a facade and I often, as a way of testing, create a command-line interface as my first UI for it before the fancier web or GUI interfaces. This UI doesn't have a dispatcher per se. It also simply throws exceptions at you. The command-line version is not friendly but scriptable (can load scripts of commands) so unit tests can be more scripted.
It seems the MVC pattern can be simplified to a "floating domain object" pattern. MVC was extended from Observable and Observer. The domain is observable and can register/add observers from each teir. The server side tends not to have this concept as everything is parsed and pushed along when a request is made towards the back and then a transition is called and within the target, methods pull down domain data.
It seems intuitive that an Observer like pattern is better if utilized within the MVC pattern, along with registration and callbacks (EJBs do this somewhat)...I don't know what exactly what it buys in functionality more than what it buys in terms of having code cleanly separated in terms of behaviours and side effects. I am currently looking at the spring framework's inversion of control pattern to see how these patterns compare in idea. Food for more thought.
In sum, (despite my wandering off this topic a bit), I think MVDC, if it should be a pattern, (and I think its not a bad idea) should go all the way or make something that truly matches it even closer but perhaps without all the complexities...(perhaps that is why it is already just MVC).
So are you trying say that for each domain we have a dispatcher? Given the current MVC frameworks out there the far majority of them are web based, ie Struts, WebWork, etc. They have one dispatcher since they are web based however if you want to use them in a JMS environment they you are saying to create another Dispatcher and maybe even another Controller (since sometimes the controllers have view related features in them). I think WebWork is moving off in that direction with their XWork component. In there case WebWork is simply a web based wrapper to their MVC engine (XWork) so if you wanted another domain dispatcher then you would make the WebWork (wrapper piece only) in whatever domain you want. I also think the Springframework does this too but I'm not completely sure.
What I was trying to say is that for each way/channel of activating a control, you would have a different dispatcher. I have with success implemented Command objects in a web-app, that could easily be reused as they are, in a Swing app. I could also easily reuse these commands to be activated by a JMS listener.
In that web-app the command objects are called by Struts-actions. The Struts-actions take the info out of the request and converts it to what the commands need (taking parameters out of the request, converting strings to long etc.). The command objects are then executed and stored in a list (on the session, since it's a web app), so I can call their .undo() method later if I want to.
I agree with John Gagon that we could break it down even further. I have thought about that too. But I kept running into areas where some of the pattern would not always be used, then. You can always use MVCD, but you don't always have persistence for instance. But then again, you don't always have a view either, so maybe that shouldn't stop us :-)
Also, I think of the smaller patterns (for instance the Adapter pattern) as merely subpatterns of MVC, gluing the parts together. The visitor pattern is but a smart way for controls to manipulate models, the decorator but a way to add views to views etc. Also, a view of a model may be the model for another view, which in turn is the model for yet a third view.
In my oppinion, you can always start your design splitting everything into MVCD. Then all the smaller patterns typically "fall out" from this division, as ways of making the 4 areas of responsibility work well together.
As you pointed out, this is EXACTLY what XWork is. It would take about 20 minutes to create a JMSDispatcher for XWork (assuming Map messages)... It would take a little longer to create some different results (the only one that would apply would be the Chaining result), something like a QueueResult, to send another message, etc... It really wouldn't take much work, if someone needed it.
Yea , but will this be a standard framework as struts ?
Struts already encourages you to follow the MVCD (implicitly) by saying that you should not put business logic inside the Strucs actions, because if you do that you wont be able to reuse that business logic outside of Struts. Struts says (somewhere) that you should take the info out of the request/session etc. and pass it to tbe business logic.
The parameters needed by the business logic should be represented in the types that are natural for the business logic, not the dispatcher(s). For instance, a business component should not take id's as String's because they are String's when extracted from the request. Instead it should take id's as long/Long, int/Integer, BigDecimal etc. eg. the type they are read to and from the database in. This will make your business logic "Dispatcher Independent".