I'm helping to build a GWT application for a client and rewrote most of the stuff to work better, shorter code, faster, etc. However in all the GUI application I've worked on (not so many really) there comes a flexing point where you just have to put a lot of rules and move logic from the listeners to some common mediator. Then some times this could get an ugly mess so you whatever small think you need to do in the listener.
Let's take an example:
form with 10-20 fields
two exclusive radio control about half of the state of the other fields (enabling, validation, input limits)
three exclusive radio controls control again almost the same fields, but in a different way (affecting calculations, enabling); they are also controlled by the above
4 or so number fields are validated on the fly depending on the previous selections and some real-time data object; they can have upper/lower limits, be enabled/disabled
one drop-down box controls the next 6 or so controls - displaying/hiding them, modifying validators
some checkboxes (shown by the above combo) activate some input fields and also determine their validation algorithm
While everything is up an running, without known bugs, there are a few coding gotchas that really bother me:
code is spread among listeners and some mediator methods.
loading the form with some preset values presents its own challenges: like data objects that might be available or not, data objects that might alter their state and subsequent field behaviour
some fields are having a default value set and this should not be overwritten by automatic filling, but if the data objects are not there (yet) then they will need to be filled eventually when the later become available
form cannot be submitted if any of the fields are not validated
My approach:
identify which fields share a common afair and move code into one place
each radio group shares a single listener implementation between its radios
default form filling is deferred until the live data is available (as much as possible) and as a result it gets called multiple times
each action has a call to a common validator method
the validator runs through all the fields in the form, calls their validators (which highlight all errors) and returns a single boolean
each relevant keypress or mouse action, data change it gets deferred to be called after 250ms from the last call; this means first call just places the validator as a delayed action, subsequent calls reset the timer
Ok, it doesn't make any sense to dwelve into more details but I'm more upset about the fact that there is no clear separation between visual actions (enabling), data actions (setting form field values), field listeners, retrieving form values and live data listeners.
What would be a good approach/pattern (next time maybe) to make sure that MVC get separated and lends itself better to maintenance? I know this is not a typical question but I've read every documentation I could get my hands on and still did not find some helpful answer.
I'd move closer towards MVP than MVC. It's clearly the way Google intends to go, so adopting it will probably mean that you're able to go with the flow rather than fight the current.
How does this affect you? Well, I believe you should accept that a tidier implementation may involve more code: not the 'shorter code' you were hoping for. But, if it's logically structured, efficient code the Google compiler should be able to trim lots out in the compiler optimisation phase.
So, move as much of the logic as you can into the model layer. Test this thoroughly, and verify that the correct level of page reset/tidying happens (all of this can be done with plain JUnit, without any UI). Next, use your Presenter (Activity) to tie the View to the Model: handling the interactions, populating the fields, etc.
you can divide a Huge class in different classes bu dividing the GUI in different JPanels. All the panels are implemented in different classes extending JPanel. Guess that would help you.
Related
My user requires any validation items (e.g. piece of data missing) to be displayed on screen, and not to be actually enforced (i.e. not to be checked to be totally valid) until further along in the process.
To accomplish this, on every save, I'll be checking for the presence of certain data. On initial object creation (of the object to be validated), I'm going to create a list of Validation items referring to specific fields (or their getters) as necessary. I will then be able to run through these items on each and every save, to check whether each item is "Valid" or not. At any point, I'll be able to display validation results to the user, as required.
Does this sound like a sensible approach? Am I missing a standardised way of approaching this task?
Usually validation is not done on save but on change. That simply means you have to attach change listeners to your fields, which then all execute your validation routine.
Listeners are only attached to the fields that are part of
validation.
Validation routine usually builds a list of errors/warnings which can be later presented in your UI
Also using JGoodies Validation will simplify your task. It is the best validation framework for Swing IMO
I'm doing a favor for an engineer friend by making him a program that helps him with the scheduling of his factory's production. Each type of product is broken down to a set of steps (they share a lot of them, but there are a few differences).
The programming issue:
Each time a new production process is registered I display a number of checkboxes representing the before mentioned steps. He can choose which steps he needs added for this particular product. If he checks a checkbox, two (or more) textfields appear where he can add additional information (starting date, duration, comments, etc...). My problem is that this is a lot of individual components and I am unsure how to handle them. Since I will need to have access to all of them at some point (the checkboxes to see if that step is needed and all the textfields for the data) I was thinking of having them all as fields, but that doesn't feel right...
Another approach could be to make a container class that groups the textfields together with the checkbox. Something like this:
ArrayList<MyComponentGroup> group;
for (MyComponentGroup cg : group) {
if (cg.getCheckBox().isSelected()) {
//access and read the data from all the textfields in this object
}
}
What is the Java programming convention or the most commonly used method to handle this situation?
Here's what I would do when dealing with tons of components and similar requirements:
I would model the relationship between options (available through checkbox selections) and the related data to fill (requirements). This model may already be available for you.
I would attempt to use PropertyEditor instances and map them to model elements.
When the time comes to save or use the data filled by the user, I would just walk the model represented on the screen, grab the associated editors and deal with the value of those editors.
I think that the approach that I described above will give you less work and potentially and it will bring more flexibility for your friend.
You'd only pay the initial cost of getting the components relationships/dependencies in a nice model as well as registering the relevant PropertyEditors for visual editing.
One approach is to consistently give each JComponent a unique name. Use something hierarchical to fit the complex process, like "Whites.Rinsecycle.enableCB". For completeness, store this String as a clientProperty in the JComponent. Then you can use that as a key in a large Map to access all the components.
Maybe not the most "elegant" (I'd tend to go with a hierarchy of JPanels with relevant fields) but for a slightly quick and dirty, moderate sized project this is reasonable.
I was wondering whether the use of a decorator pattern is good in case I want my model ("M part" of MVC) to raise Exceptions depending on their origin. I explain myself.
I have a class called Game which is a part of the Model. I have two Views : a GUI and a command line. I want my model to raise an Exception for command line view when the user enters a character instead of a number (for example). Of course I don't want this Exception to be handled by the model as it "belongs" to the command line and not to the Model itself.
To encapsulate those two different behaviors, I plan to decorate the Game class with two classes : CommandLineGame and GUIGame which have only one attribute : Game and handle their own kind of Exception. Is it a good idea ? Is there a better one ? The problem of such a solution is that every model class raising Exception depending on its origin has to be decorated...
What you are describing in the example is "input validation". Strictly speaking*, this belongs in the Controller ("C Part") of MVC.
The separation of concerns for MVC decomposes as follows:
View is there to 1) present a UI for the user to evaluate the state of the program (Also, what your program looks like visually) and 2) to receive the user's expression of intent (receive raw instructions on what they may want to do)
Controller is the actual interpreter of these "actions" or "intentions" from the user. It decides what it means for a user to click a particular button and what to call in your model. It decides whether a particular input actually makes sense given context from the UI (and in some case from the model).
Model should be View/Controller agnostic (Meaning the model should have no knowledge of the View/Controller). It should only be about the internal representation of what you are trying to "model". The advantage of doing it this way: you can have many different UIs, or change your existing UIs without affecting the model.
Overall, the idea is to lower coupling and increase cohesion.
I hope that makes sense =)
Depending on the language / framework, the lines between MVC components get blurred a bit. Some idioms will lump most of Controller into the View, but the encapsulation of logic should stay relatively similar.
*In practice, for defensive programming, input validation is done twice for mutual suspicion: they are broken down into client-side mediation and server-side mediation:
In this case, the Model part should handle the "server-side" mediation: it should check that the arguments passed to its functions actually make sense before proceeding.
Similarly, the Controller/View part should check the input as part of "client-side" mediation, so that it can warn the user right away, without passing it back to the model, and then eventually back to the view.
It will keep your code very clean, something i like a lot from an academic perspective.
On the other hand do you need to introduce this kind of design complexity for a simple problem like this?
So, if you need the code to be clean... GO for it.
I have changed my app to use MVC and it has gotten pretty slow.
Description:
The application has a number of 5 composites, each composite represents different data and is not always showing
The app is using MVC and I am passing the model to each composite when an update occurs.
I am rebuilding a Tree (and all tree items) every time a notify is recieved, however, only one of the tree items would have changed, so this is possibly a waste.
Due to the style of the app I have to even notify() for insignificant things like changing the text in a text box or selecting a menu because I have a saved icon that turn to unsaved whenever something is changed in the tree Item.
All the composites are implementing the same Observer Interface, so all are getting updated on every notify().
Can someone give me some tips on what I should do to speed this app up. Which of the above might be more CPU hungry than others, ie, is rebuilding a Tree with < 20 items on every notify() going to use that much CPU time, do I need to re-design this? Should I create a seperate interface such as SaveStateChanged that will only notify the tree, or is this just a waste of time.
When an application is getting slow, then most time is often not spent performing the JavaScript calculations themselves (e. g. I don't believe, that just calling a lot of observers is a problem - it depends on what they do!). Very often, slowness is caused by things like redundant layout (e. g. when each of the observers causes a layout call). Sometimes, lots of DOM manipulations can also be a problem (mainly with Internet Explorer).
I would suggest to play a little bit with Speed Tracer, especially the redundant layout example. If that's not the specific problem in your application, you should be able to take a similar approach as shown in the example to track it down. Use markTimeline("String") to make special parts of your code show up clearly in Speed Tracer's graphs.
The first step you need to take is to isolate exactly where the performance problem is occurring. You've identified some good possible candidates, but you'll want to back that up with cold hard stats.
You may find you only need to address one of the above points, or that there might be another sticking point entirely
I suggest you get rid of the Observer interface in favour of something more finegrained. Look at the MVC architecture in Swing where a JTree is associated with a TreeModel and implements TreeModelListener interface to hear of changes to the model. The TreeModelListener interface has specific methods called by the model to indicate nodes changing, being added or removed from the tree. In addition it has a TreeModelEvent which provides even more data about which nodes are affected. If the model tells you precisely what has changed you will have a lot more scope for reacting intelligently from your listener implementations.
I inherited this gigantic legacy Java web app using Struts 1.2.4. I have a specific question regarding Actions. Most of the pages have exactly one Action, and the processExecute() methods are hideous monsters (very long and tons of nested if statements based on request parameters).
Given that Actions are an implementation of the command pattern, I'm thinking to split these Actions into one Action per user gesture. This will be a large refactoring though, and I'm wondering:
Is this the right direction?
Is there an intermediate step I could take, a pattern that deals with the mess inside the monolithic actions? Maybe another command pattern inside the Action?
My way of dealing with this would be:
dont do 'everything at once'
whenever you change anything, leave it better than you found it
replacing conditionals with separate Action implementations is one step.
Better yet: Make your implementations separate from the Action classes so that you can use it when you change frameworks
Keep your new Command implementation absolutely without references to Struts, use your new Actions as Wrapper around these implementations.
You might need to provide interfaces to your Struts ActionForms in order to pass them around without copying all the data. On the other hand - you might want to pass around other objects than ActionForms that are usually a bunch of Strings (see your other question about Struts 1.2 ActionForms)
start migrating parts to newer & better technology. Struts 1.2 was great when it came out, but is definitely not what you want to support in eternity. There are some generations of better frameworks now.
There's definitely more - Sorry, I'm running out of time here...
Struts Actions, in my mind, shouldn't have very much code in them at all. They should just interact directly with the request and response - take some data from a form or a request parameter, hand that info off to the Service Layer, and then put some stuff in a Response object or maybe save some data in the user's session.
I'd recommend staying away from doing inheritance with action classes. It sounds like a good idea at first but I think sooner or later you realize that you're shoe-horning things more than you're actually making the code base robust. Struts has enough base actions as is, if you're creating new ones you've probably got code in the web layer that shouldn't be there.
That is just my personal experience.
I've dealt with this type of thing before. A good first step is to insert another base class into the inheritance chain between Action and one of the original monstrous action classes (lets call it ClassA). Especially if you don't have time to do everything at once. Then you can start pulling out pieces of functionality into smaller parallel Action classes (ClassB, ClassC). Anything that's common between the original ClassA and the new refactored classes can be pulled up into the new base class. So the hierarchy now looks like this:
Original Hierarchy: New Hierarchy:
Action Action
| |
| BaseA
(old)ClassA |
+--------+----------+
| | |
ClassB (new)ClassA ClassC
Go one method at a time
Record some test cases you can play back later. Example here (make sure to hit as many paths through the code as you can, i.e. all user gestures on the page that call this action)
refactor the method to reduce its complexity by creating smaller methods that do smaller things.
Re-run tests as you do this
At this point, you have refactored version of the big huge annoying method. Now you can actually start creating specific actions.
You can use your newly refactored class as a base class, and implement each specific action as a subclass using those refactored small methods.
Once you've done this, you should have a good picture of the logic shared between the classes and can pull-up or push-down those methods as needed.
It's not fun, but if you will be working on the codebase for a while, it will save you time and headaches.
Tough problem but typical of early web app development.
First things first you need to start thinking about which logic constitutes business behavior, which logic constitutes "flow" (i.e. what the user sees), and which logic gets the content for what he sees.
You don't have to go down the route of factories and interfaces and all that; retroactive implementation is far less useful... but consolidating business logic and data retrieval logic into delegates of some kind... and leaving the struts actions to determine page flow based on success/failure of that logic.
From there you just have to take a few weeks and grind it out
One long method is never good, unless it happens to be a single switch statement where the cases are very short (token parsing or something like that).
You could at least refactor the long method into smaller methods with descriptive names.
If at all possible you could start your method with recognizing what it is it should do by examining the form, and then if/else your way to the various options. No nested ifs though, those tend to make code unreadable. Just
enum Operation {
ADD, DELETE;
}
...
Operation operation = determineOperation(form);
if (operation == Operation.DELETE) {
doDelete(form);
} else if (operation == Operation.ADD) {
doAdd(form);
}
If you can go that far you have your logic nice and clean and you can do whatever refactoring you want.
The hard part is to get your logic clear, and you can do that in steps. Don't choose a pattern untill you understand exactly what your problem is.
If you're planning to refactor the code you should make sure to write tests for the existing code first so you can be sure you haven't altered the functionality of it once you start refactoring.