I had a discussion today with a guy at work about a point in David West's book, Object Thinking. The lines in question were something like:
"If you wrote a well designed OO functional equivalent version of an application that was written by a programmer that didn't understand OO, then the number of lines in the application would be at least one order of magnitude less, perhaps two. In addition, the time to market would be at least 50% less, perhaps 70% less."
His point was that this statement was unqualified. I'd agree. But when I read the book, I never really worried about that - as I believe that a proper OO program would definitely have significantly less lines than a regular program.
I have done some bug fixing and then refactoring (yes, they should be separate activities) and removed an amazing amount of code. All this without removing functionality and improving quality, simplicity, readability, robustness and reuse (At least I hope I did!). All by following simple OO concepts.
I tend to go on about this, but Duplication in all forms is your enemy. Blatantly obvious duplication is an issue, but you have to keep you eye out for functional duplication as well.
For example, suppose that you wanted to copy a set of phone numbers from an object obj that allowed them to be 30 characters to another that only allowed them to be 15:
obj1.homephonenumber = obj2.homephonenumber.tostring().substring(0,15);
obj1.workphonenumber = obj2.workphonenumber.tostring().substring(0,15);
obj1.mobilephonenumber = obj2.mobilephonenumber.tostring().substring(0,15);
This is an example of functional duplication. This should be changed to:
obj1.homephonenumber = NumberHelper.ConvertToOldFormat(obj2.homephonenumber);
obj1.workphonenumber = NumberHelper.ConvertToOldFormat(obj2.workphonenumber);
obj1.mobilephonenumber = NumberHelper.ConvertToOldFormat(obj2.mobilephonenumber);
And depending upon the hierarchy of the obj object, the function ConvertToOldFormat could be placed upon obj's parent.
Now for the reasons:
- the ConvertToOldFormat function is now testable via NUnit or similar
- the code is more readable
- the ConvertToOldFormat function could be re-used anywhere that the functionality is required
- the intent of the code is obvious
- if the rules regarding the convert process change, then there is only one place where it has the be changed
- the result of the ConvertToOldFormat function is consistent
- you can add preconditions, postconditions and invariants to the NumberHelper object to make your code more robust
- others will marvel at you abilities
There are so many opportunities when writing code to make these kind of choices - added together, your application can be so much better.