One effective approach I've found in software development is the practice of alternating between writing design documents and actual coding. This iterative process has multiple benefits.
Starting with a high-level draft of a design document provides a preliminary architectural overview. It sets the stage by outlining the software's main objectives and offers an initial roadmap for the journey ahead. Yet, this is not an exhaustive exercise; the purpose is to sketch, not to draw every detail.
When transitioning from the design phase to coding, new insights invariably emerge. These insights, often unanticipated during the initial design phase, can lead to significant refinements. Incorporating these learnings back into the design doc ensures it remains a living document, continually updated to reflect the project's evolving state.
The idea of starting with a design document aligns with the principles of Domain-Driven Design (DDD). At the heart of DDD is creating an accurate model that represents the domain, its constraints, and its intricacies. Similarly, the design doc seeks to model the software's architecture and objectives.
Keeping design documents updated and close to the code can be seen as parallel to DDD's concept of a ubiquitous language. Such a practice ensures a shared understanding, bridging any knowledge gap among team members. Furthermore, as DDD encourages collaboration and discussion about the domain, design docs can serve as catalysts for these essential conversations.
While some developers may lean towards diving directly into code, alternating between design and development offers a balanced perspective. It promotes clarity, foresight, and adaptability, qualities indispensable in a constantly evolving domain.
For those skeptical about the utility of design docs, consider them as extensions of READMEs. Naming them DESIGN.md
or something similar and placing them in the project repository ensures they're accessible and continually relevant.