source | link

This isn't really an answer so much as a long comment (Because these answers have already been presented).

I've found that striving religiously for two factors--clean, usable interfaces and no repetition have made my code much better and over time have made me a much better programmer.

Sometimes eliminating redundant code is HARD, it forces you to come up with some tricky patterns.

I usually analyze what MUST change then make that my goal. For instance, if you are doing a GUI on a client to update a database--what do you need to add "Another" one (another control linked to the DB?) You need to add a row to the DB, and you need the position of the component, that's it.

So if that is your bare minimum, I don't see ANY code in that--you SHOULD be able to do it without touching your codebase. This is amazingly hard to attain, a few toolkits will do it (usually poorly), but it's a goal. How hard is it to get close? Not terribly. I can do it and have done it with zero code in a couple ways, one is by tagging new GUI components with the name of the table in the DB, another by creating an XML file--the XML file (or YAML if you hate XML) can be really useful because you can link validators and special actions to the field, making the pattern extremely flexible.

Also, it doesn't take more time to implement solutions correctly--by the time you've shipped most projects it's actually cheaper.

I can point out that if you rely heavily on Setters & Getters ("Bean Patterns"), Generics & Anonymous inner classes you probably AREN'T coding generically like this. In the above examples, trying to force in any of these will really screw you up. Setters & Getters force you to use code for new attributes, Generics force you to instantiate classes (which requires code) & Anonymous inner classes tend not to be easy to re-use elsewhere. If you are really coding generically, these language constructs aren't bad, but they can make it hard to visualize a pattern. For a totally nonsensical example:


Looks fine--not really redundant at all--at least not in a way you can fix, right? But it causes you to add a line when you want to add a "Middle Name", so it is "Redundant code"


Does not need new code for this task--it simply requires that some attributes in "screen" are tagged with a "Name" attribute, but now we can't copy address, how about this:

user.getAttributesFrom(screen, NAME_FIELDS, ADDRESS_FIELDS);

Nicer, a var-args lets you include a group of attributes (from an enum) to gather from the screen--still you have to edit code to modify the types of attributes you want. Note that "NAME_FIELDS" is a simple enum instance--fields in "screen" are tagged with this enum when designed to put them in the correct categorie(s)--there is no conversion table.

Attribute[] attrs=new Attributes[]{NAME_FIELDS, ADDRESS_FIELDS, FRIENDS_FIELDS};
user.getAttributesFrom(screen, attrs);

Now you've got it to where you are just changing "Data". This is where I usually leave it--with the data in the code--because it's "Good enough". The next step is to externalize the data if that is ever needed, so that you can read it from a text file, but it rarely is. Refactorings "Roll up" like this a lot once you get into the habit, and what I just did there^ created a new enum and pattern that will end up rolling in many other refactorings.

Finally, note that good generic solutions to problems like this are NOT language-dependent. I've implemented a no-code-per-loc solution to parsing a text GUI from the command line of a router, updating it on the screen and writing it back to the device--in VB 3. It just takes dedication to the principle of don't write redundant code, ever--even if you have to write twice as much code to do so!

The Clean Interface (Fully Factored & doesn't allow illegal stuff to pass through) is important too. When you factor an interface between two units of code correctly, it allows you to manipulate code on either side of the interface with impunity and allows new users to implement to the interfaces cleanly.

    Post Made Community Wiki by Bill K