As I mentioned I would do after completing my class on the subject, let's revisit software design.
The biggest takeaway from the class I took is that the detail in a design document should be adapted to the team, company, and situation. The class asked for highly detailed documents and required sections and details that really weren't all that beneficial for most development environments while also not emphasizing other sections enough.
Including a class dictionary, listing out all properties and methods. These tended to take a large chunk of the overall document and were highly duplicitous to the code that matched the design doc. Furthermore, these class dictionaries required deep upfront thought, only to need constant updating as the implementation moved forward, as details only revealed when a compiler is around came to light.
Scalability, performance, and testing sections were not given enough structure. Class dictionaries needed so much time and attention that these other three critical sections got basic overviews. This was totally fine in a class environment since we built MVP implementations for these designs and never actually deployed these systems. In a real situation, though, scalability, performance, and testing are critical parts of a software design that won't just appear in the implementation. These aspects are critical to think about in advance, as some implementations won't support the scale of performance desired for the system you are building.
Succinctly: Ensure the information you would need to implement this system is there.
That includes context as to what the system is aimed to do, a description of the classes and protocols that will make up the core implementation, and the scale and performance needs of your system. Do you need to list out all the methods and properties in each class? No. If there are some you know must be included in a specific class, that can definitely be specified in your doc, but trying to think through all methods and properties before writing code is inefficient -- some of these details will be more efficiently determined when a compiler is helping you!
In addition to implementing the system, how to operate the system once deployed (along with a deployment plan) is best to include within a design document. Including scalability information and expectations for performance makes it easy to understand down the road what needs to be done to increase the scale further when what you've built is taking off.
Even though there might be varying schools of thought as to what exactly is in a design document, it's fairly clear the benefits:
Having a clear and defined plan lets you do many things:
Ensuring that the people reviewing code for a project have signed off on the design document ensures that there is architectural alignment from the start, which avoids painful code review situations where days of work must be thrown out. Architectural discussions should never happen in code reviews, but they often do when design documents aren't agreed upon ahead of implementation. It's in these documents that those discussions should live, as there's no bias from the time spent on a particular approach.
Depending on how big your team is, this could be a non-issue. In bigger teams, though, once a project gets running, there are often many different stakeholders from other teams and/or disciplines curious to learn more about the project. They may have something on their team that would make sense to integrate or prepare some marketing communications for launch. In either case, a well-formed design document can give both these individuals answers without distracting anyone on the team. Without a design document, this would typically mean a meeting would be called, slowing down the project's development.
The system you build will not run itself! Once it's up, there will be an ongoing maintenance cost of some kind, with a wide range depending on exactly what you're building. A design document helps ensure it's clear how to operate this given system and provides expectations for what scale the system can reach as designed and what performance can be expected.
Whenever the team grows and someone new has to learn a new codebase, a design document that is well written is an invaluable resource. It puts code into higher-level context and helps engineers learn the systems they are about to work on.
Design documents of some form are beneficial in software engineering. The exact format is really dependent on your team and your organization. As long as it can answer what you need it to, that's what is important. Be wary of overdoing the design document, though, as it can be a waste of time better-spent coding -- question why each element of a document template your organization uses is in there, and remove any that aren't needed. In my experience, a class dictionary with functions and variables laid out for a class is a step too far for design documents. Unless, of course, if the team is so junior, it helps them!
The next article will be a collation of my current series of #bendevtip time management posts! As always, thank you for reading
Benjamin is a passionate software engineer with a strong technical background, with ambitions to deliver a delightful experience to as many users as possible. He previously interned at Google, Apple and LinkedIn. He built his first PC at 15, and has recently upgraded to iOS/crypto-currency experiments. Benjamin holds a bachelor's degree in computer science from UCLA and is completing a master’s degree in Software Engineering at Harvard University.