Let's say that you took your car into the shop, and you wanted to get your oil changed. You sat for an hour or two and you ask the mechanic, what's going on? what's taking so long? he responds "well you hit 40,000 miles so we went ahead and changed the air filter, turn signals, brake pads, brake fluid, did a transmission flush, differential flush, radiator flush, water pump replacement, timing belt replacement, and cleaned out your car. your total will be $1400, it won't be done until next week, and we don't really accept credit cards or checks so if you have cash that would be nice"... you'd be a little upset, don't you think?
That's where simple design comes in: In extreme programming, for most general cases we're told to
- Use the simplest thing that may work
- don't write it if YAGNI (you aren't going to need it)
- write once and only once (no duplicate code)
because it's
- easier to understand and maintain
- requires the least amount of work
- gives the customer the most amount of business value for that iteration (ROI)
Think back to a time when you were in some code that was highly abstracted and how confusing it looked. (Microsoft's Data Access layer factory for patterns and principles comes to mind). Now try to imagine if you applied that level of abstraction to all of your code, in some grandiose attempt to welcome change throughout the application...
public class BusinessObject<T>
{
public T Fetch(ObjFactory<T> factory, SelectionFactory<T> selectionFactory){}
}
--makes sense but horrible to look at unless you absolutely need something like this, don't do it
--you may recognize this code, if so.. think "would you need all of this? always? How much bloat am i PAYING to maintain?"
It would be completely unintelligible very near impossible to maintain (especially with any amount of turnover in your development group)
Simple design is honestly something that is difficult to implement, because
A) One person's simple is another person's complex
B) we've been burned so many times by changes
C) we may already work with existing complex code
So what can we do? How can we get started with this simple design?
- Get unit testing, preferably automated built+automated testing. This encourages and allows for people to couragously refactor code for it to be simpler.
- encourage collaboration, if the team communicates more about how something should work they'll code more alike and legible for everyone.
- educate people to follow the 3 XP mantras (simplest first, YAGNI, code once only once)
Am i saying not to use pre-built components? no, if the most simple and easy to understand thing is to plug in some sort of third party component then buy it and put it in there. The bottom line is the bottom line here... the customer's ROI is the most important thing on our minds with this practice.
Am i saying that you can't abstract things? in a way, yes... don't abstract until the absolute moment that you need to. If your sprint is to write a printing component that prints to 1 type of printer, then make it print to only that type of printer and move on to the next thing on the list.