Philosophy of Building Software
While there are many ways to be successful, I have several foundational beliefs.
Fundamentals
Most human endeavors have a set of skills and a language that is assumed and common among professionals or experts. Chefs don’t think in recipe steps, they think and communicate in techniques and ingredients. Musicians don’t think in individual notes, and chess players don’t think in individual moves. They all operate at a higher level of abstraction. Software practices are very fragmented, so this doesn’t seem to quite exist, but I think it will be needed in order to handle the ever more complex systems we’re building.
At a minimum, fundamental skills involve process work like version control, testing, and group collaboration, as well as generic programming ability sufficient to make a first step working solution to most business problems almost trivial.
A possible next step might be category theory, or anything that provides a coherent, comprehensive worldview. A team that could on-board a certain knowledge set, and then operate at a higher level of abstraction would be very effective.
Chunking Is Key
Software gets complex extremely fast. Since most people can only handle 4-9 pieces in short term memory at once, and most problems have more moving pieces than that, we have to break problems down into manageable chunks. This is why we don’t write everything in Main(), and the key to scaling at all levels. It’s the core of design, and knowing how to draw and keep boundaries is important. This is why functional techniques and tools are promising.
Teams Need Decoupling Too
Coordinating separate teams for all the necessary parts of a software project quickly swamps the process. Just like we can’t have completely unrelated sections of the codebase introducing bugs when they require changes, we can’t have changes in what could be completely independent areas of an organization rippling through the entire system. This involves many subtle trade-offs between functional knowledge and domain knowledge. Grouping QA or OPS or DBA services together is similar in trade-offs to grouping Views or Models or data access together.
Solve the Right Problem
Bridging the gap between humans and machines is at the center of using software to solve problems in other domains. Inability to solve the right problem is the cause of many software failures and setbacks. Techniques to minimize this risk, like frequent delivery, short iterations, and demos will always be important. Domain Driven Design’s focus on ubiquitous language goes a step farther, and groups that can fully embrace the process (apparently GitHub’s lawyers write in Markdown and collaborate with pull requests) will have an advantage.
Focusing on Quality Pays Off Early
Automated testing, design, continuous integration, and other quality measures and often viewed as an up front cost that only pays off down the road. While it’s true that a one-off script written in under a day and only used once won’t benefit from a quality focus, I’ve found the benefits happen in a matter of days or weeks, not months. Very little software has a lifetime short enough that a focus on quality doesn’t pay dividends very early.