3 ms·
I feel your pain - I struggle with the same thing. But I think it's possible, to some extent, to have the best of both worlds. An ideal of clean, logical desig
by lukev 16y ago
I feel your pain - I struggle with the same thing. But I think it's possible, to some extent, to have the best of both worlds.
An ideal of clean, logical design actually satisfies both #1 and #2. You don't write any more than you need to, but you architect it sensibly so if you need to modify it in the future, there's a natural way to do it.
A case study: you are responsible for maintaining a moderately sized mailing list.
Type 1: Maintains a comma+newline separated list of name/email pairs in a text file, parse it with a 3 line perl script that sends an email for each regex match. Done in 15 minutes. YAGN anything else.
Type 2: Builds a fully relational model in a database with seperate tables for names and addresses, backed by Hibernate with a complete class hierarchy including AbstractRecords (in case you want to store records other than name/email pairs), RecordFactories (In case we need to generate lists of records from another source), AbstractRecordDAO (in case we need to use a different Database or ORM framework), EmailFactories, AbstractMailerImpl, etc, etc, etc, planning in the architecture for anything anyone might ever want to do with a mailing list.
Both of these are wrong, IMO.
The correct solution is to write one database table, or one cleanly formatted file, with a program with perhaps two classes that abstract apart the data loading and the mailing tasks. One class loads the data into a simple Map structure, and the other that handles iterating the map and doing the mailing.
It only takes a bit longer to write than #1, and is infinitely simpler than #2. It doesn't anticipate every future need, but when one comes, there's a logical point to start adding the functionality. If I have to do something new with the list, I don't have to completely rewrite my program (like #1 does), I just write a new class that uses the existing data structure. Just as extensible as #2, with a tenth of the work. And easy to see what's going on.
- bsaunder 16y agohmm... If I have to do something new with the list, I don't have to completely rewrite my program (like #1 does) You said #1 only took 15 minutes. Hardly seems like a big cost. If you never have to rewrite, #1's the right answer. Or if the rewrite includes functionality never even anticipated in your "correct solution". If it's that small, starting over with a clean slate may be faster than fitting in new functionality.
- lukev 16y agoThis is a small example, so yeah, you're right, when the absolute times are so small. But say instead that it's a larger problem, and that #1 takes one day to build, #2 takes a week, and the "preferred" solution (call it #3) takes two days. Then along comes your change request. It will take most of a day to rewrite #1 to do something never anticipated, but it can be slotted into #2 or #3 in about an hour. Now you've broke even between #1 and #3, and that's only the first change request. Any real system is going to get many more. These numbers are pulled out of thin air, of course, but they're pretty accurate according to my development experience.