People who haven’t written large programs think that writing software is easy. All you have to do is break a big problem into smaller problems until you have something so small that it’s easy to program.
The problem is putting the pieces back together. If you’ve only written small programs, you haven’t had many pieces to put together. It’s harder to put the pieces together when you write a large program by yourself. It’s even harder when you work on a large program with other people.
Synthesis is harder than analysis. Or as Perdita Stevens put it, integration is harder than separation.
The image above is a screenshot from her keynote at the RC2020 conference on reversible computation.
Related post: The cost of taking things apart and putting them back together.
“Everything should be built top-down, except the first time” –Alan Perlis
Who I believe was paraphrasing Luiz Fernando Capretz:
“…for those who have no previous knowledge about the application domain, it is better to rationalize in terms of low level abstractions, and instantiate some objects at that level to depict the overall software behavior. In broad terms, it could be concluded that everything should be built top-down, except for the first time.”
excerpt from Search Results
Web results
Object-Oriented Software: Design . – Page 150
I’m also reminded of Feynman’s Appendix to the Rogers Commission Report on the Space Shuttle Challenger Accident:
Indeed, and this is something that is intrinsic in reductionism: the belief that once you get the micro details worked out, how they all fit together is trivial
something I try to emphasize in courses I teach.
Interfaces. Get those right, and they’re the glue needed for diverse teams to productively work cooperatively.
In our workflow, we add features “where we can”, then do a separate pass to clean up the interfaces (and abstractions). This churn is managed by having very senior folks do code review, to keep an eye on the balance between rapid progress, cruft, and “technical debt”.
We just did a major (massive, monstrous) beta release that is scary in how klugey it is, but it exposes the required features to the customer, and we’re now doing a “stabilization” pass to improve current functionality while preparing for the next beta release.
The evolution of the interfaces can be surprising, especially when suddenly realizing that something we’ve done for years was wrong all along. Just yesterday, one PR removed 15 KSLOC from our code base, and everything “just got better”. That change took one programmer one day to see and implement, though granted he’s able to view our code from dizzying heights.
tell me about it :(((…. as a side note, you must split with the idea that it should be integrated, and constantly think where and how that integration must occur. This means if you are doing it right the two phases blend together, and while splitting you actually design hundreds of programs, while you (re)model a single problem. That being said if you are designing a framework(you do not have a concrete enough solution space to maintain in your head) you are effectively attempting to maintain integration across thousands of probable-to-potential sub-spaces and that makes you consider madness as an escape strategy.