I've been using the MVC pattern in my applications for years (with full separation of the controller from its views).
Having to implement several hundred views to represent a little over 100 model's for a potential contract, this time around I'd like to reduce the development time of my UI tasks and also add a few additional features (view decoration, etc).
I'm curious to find out if anyone has used or even implemented a design such as the one I'll explain bellow and if so, what were your pros and cons were.
Without getting into too much detail, I'm going to simply elaborate on an example of an API I have been juggling with in my head for a few days along with some explanations a bit later on, so here goes:
Model m = dao.getInstance(ID); // ie: possibly fetch it from a database VTextField text = new VTextField(); // simply 'extends' the Swing components text.setModel(m); Decorator deco = DecoratorFactory.getInstance(); // specific to a customer text.setDecorator(deco); Controller c = ControllerFactory.getInstance(m); text.setController(c); Validator v = ValidatorFactory.getInstance(m); // get the current validator c.setValidator(v, "validateText");
So in the example above, the idea is that I will have the same application for several clients. Although each have accepted the general usability, each want their branded L&F to it, some based on business rules (ie: a text field has errors, the background of text-field should be in yellow with red fonts... an other want the text in black and the background yellow with a red border).
What I was thinking was that on any event (on focus, loss focus, key typed, etc), the component would basically invoke the controller. In turn, the controller (through reflection) would invoke the validator. If validation passes, the controller simply updates the model. If validation fails, the controller does not update the model.
The controller would keep a state of all of this (viewing, editing, editing with error, etc) and would delegate to the decorator which would adjust the L&F of each component based on client demands.
This would avoid a ton of 'if/else' blocks directly in a single controller. The controller, validator and decorator knows which concrete instance to load based on which client is running the application. This way, I can separate the logic for each client and reuse when it is shared behavior.
The decorator doesn't overide the paintXXX() methods, but simply calls the 'setBackground(c)', 'setBorder(b)' and all of these setter methods already available in the Swing components. The reason I extend each component is simply to add the 'setModel(m)' and 'setController(c)' methods along with any framework logic I'll need. When the component is in 'view' mode, it usually doesn't paint the border and background and all that stuff (looks more like a traditional web page). When it is in 'edit' mode then it looks more like a Swing component.
When I design application UI's I usually stick to only a few major components (JTextField, JTextArea, JPanel, etc). So it wouldn't be too much work on that side.
I have not started to implement any of this stuff just yet, so if you know of existing libraries which does something similar, please point them out.
My only real issues I have at this time is how to handle cases where component depend on each other. For example, two text fields having an int value. If one field is odd then the other must also be odd and if one is even, then the other must be even. When the validation occurs, the validator would need the value of the other text field to properly validate... so I still have not ironed out that part.