9 Takeaways for Product Managers from A Philosophy of Software Design
A Philosophy of Software Design by John Ousterhout is full of examples for writing well-designed software. Let’s look at those concepts through a Product Management lens to see what we can learn about effectively managing a software product project.
“If we want to make it easier to write software, so that we can build more powerful systems more cheaply, we must find ways to make software simpler.”
I recently read a great book (A Philosophy of Software Design by John Ousterhout) about how to design software systems to minimize their complexity. Complexity makes it difficult, risky, and costly to iterate on and improve a software system. The ability to iterate is a critical component of building a valuable digital product. Good software design, according Dr. Ousterhout, is then all about managing complexity. Not surprisingly, good software product management is also all about managing complexity.
The book is intended for a technical audience, and leans heavily on specific technical examples for mitigating complexity in your own code. However, the general concepts in the book are relevant for anybody who works on a digital product team. I gained a much deeper understanding of the nature of complexity in software development, and the inherent value of combating complexity in all the decision-making that goes into building a digital product -- not just in the structure and organization of the code.
Here are 9 takeaways from A Philosophy of Software Design that every Product Manager can (and should) keep in mind to ensure the success of your digital product.
On the role of a Product Manager
A Product Manager is responsible for quality and satisfaction not just in what we make, but also how it’s made. This manifests itself in a variety of roles and functions across a project and product lifecycle. Three of those are: simplicity advocate, system visualizer, and problem decomposer.
1. “The overall goal is to reduce complexity.”
Complexity is anything related to the structure of a software system that makes it hard to understand and modify the system. More than anything, my biggest takeaway from the book was: for a Product Manager to be the advocate of a digital product, she must also be an advocate for the minimization of its complexity. This is especially true for Product Managers at digital agencies, who are often ushering a product team through early stage development. Engineers are most affected by complexity, but are sometimes not the best-positioned to advocate for its minimization. As the PM, you are in a unique position to empower both the client and product team to make decisions that minimize complexity as much as possible. This doesn’t mean constant pushback or obstinacy. Human ideas and real-world concepts are complicated. And as Dr. Ousterhout explains in the book, complexity is inevitable. By advocating for the simplest solutions to the highest-priority problems, you are driving the team toward creating the most valuable product for the client and their customers.
Takeaway: Being the product advocate is being an advocate for simplicity, plain and simple.
2. “If you can visualize a system, you can implement it in a computer program.”
As Dr. Ousterhout explains in his book, “All programming requires is a creative mind and the ability to organize your thoughts. If you can visualize a system, you can probably implement it in a computer program.” My takeaway is that you don’t need to be a programmer to manage a product, but you do need to be able to visualize the system -- to take client requirements and business logic and work with the team to distill it into an abstract system. As a Product Manager, you should own that system throughout the project lifecycle, including documenting it (perhaps with a concept model) and facilitating ongoing shared understanding of it with the product team and client. You should also understand how changes to one part of the system impacts the rest of the system.
Takeaway: As the System Visualizer, you are the glue between the product design system and the software system. Conceptualize the system - including the underlying data objects - and foster that understanding with the entire product team.
3. “The most fundamental problem in computer science is problem decomposition.”
“The larger the program, and the more people that work on it, the more difficult it is to manage complexity.” Taking a complex problem and dividing it up into pieces is the hardest part of computer science. It’s also the hardest part of approaching a large-scale software development project, especially when many engineers are working together. As soon as you have an idea of the system, you want to start building it to see if your system holds up. But how is the work going to be broken up among the engineers, and what’s the build order? Owning (or helping to manage) this critical piece of product projects is yet another way the PM can help reduce complexity.
Takeaway: Breaking out the product project work into actionable design and development tasks early and throughout the lifecycle of a project is critical. It’s the hardest and simultaneously most important problem to solve. Someone needs to be doing this on your product project, and it takes a certain level of technical knowledge. At Viget, the Product Manager (as Problem Decomposer) typically pairs with the Tech Lead to figure out who’s doing what to get started, and how work will be broken up throughout the project.
On product project process and execution
The book also surfaced some key insights that Product Managers can carry over into their product project planning and execution. Keep these in mind as you work with your Project Manager to formalize your project plan.
4. “Software (system) design is a continuous process.”
A Philosophy of Software Design does a great job of explaining why the waterfall model of planning and architecting rarely works well for software. Software systems are more malleable and intrinsically more complex than anything we build in the real-world, making it impossible to visualize the system design and all its complexity for a large software system well enough upfront to understand all the implications before building anything. As a result, any initial planning will have problems that don’t become apparent until implementation is well underway. Instead, software system planning needs to be a continuous process that spans the entire lifecycle of the project.
Takeaway: Product Managers are in a great position to promote and facilitate a continuous, agile approach to software design and development, and champion that process throughout the project. We recommend starting with the simplest implementation of core functionality, and layering on complexity once that core functionality is in place.
5. “Incremental development means that design is never done.”
Similar to the previous point, it’s critical to remember that product design doesn’t end when the first round of wireframes are complete. Instead, Product Designers and Engineers should work together, incrementally, and throughout the full project. Having the cross-functional team working together on the same features at the same time will ensure that rapid feedback from Engineers can be incorporated into designs, and vice-versa.
Takeaway: Collaboration with Product Designers is continuous and consistent. Product Managers should work with Project Managers to ensure that Product Design time is accounted for throughout the duration of the development process, not just in the beginning, and that the cross-functional team is set up to succeed with interdisciplinary collaboration and communication along the way.
6. “Strategic programming requires an investment mindset.”
When deadlines are looming, it can be easy to fall into the “Build Trap” -- focusing on getting as many features as possible working as quickly as possible. However, Dr. Ousterhout argues that good software design requires a more strategic approach, where you invest time in producing clean designs and fixing problems as they arise. This investment of resources can sometimes be a tough thing to advocate for (to stakeholders) in early development, but it will save time down the road and keep the codebase clean and easy to work with.
Takeaway: Build in time in your product plan for strategic programming (refactoring previous work, tech debt clean-up, etc.) and communicate the purpose and value of this time to your client. This is another area where the Product Manager can advocate for Engineers proactively, making their jobs easier and creating a better end-product.
On day-to-day Product Management
A Product Manager often wears many hats on a digital product project, from gathering requirements and defining features to expediting delivery and running quality assurance testing. A Philosophy of Software Design encouraged me to evaluate those responsibilities through the lens of reducing complexity, and consider how (and when) a PM can proactively minimize complexity through her work. Here are three ways you can look to advocate for simplicity in your day-to-day project work.
7. “Exceptions contribute disproportionately to complexity “
As you’re gathering and reviewing requirements, it’s almost inevitable that edge cases will come to light. (Like I mentioned earlier, real-world human ideas are complicated by nature.) For example, what happens if a Classroom has no Students? How about if just one of the 18 offices needs to have two Office Managers, while the rest only have one? As the Product Manager, you can ask yourself (and your client and your team) about edge cases and exceptions, and manage those when they arise.
Takeaway: To mitigate complexity on a project, the Product Manager should lead the charge in flagging exceptions during requirements-gathering and feature definition. When the PM takes responsibility for anticipating edge cases, avoiding them (if possible), and planning for them (if not), it greatly reduces the likelihood that they will manifest as unforeseen requirements down the road. This also applies to reviewing designs, as edge cases are sometimes easy to overlook.
8. “It is easier to tell whether a design is simple than it is to create a simple design.”
Product design and software design are intrinsically linked, and in our typical process, design comps are reviewed by the full team (as well as our clients) for buy-in as the digital product is being created. While the Product Manager typically reviews designs for alignment with requirements, this can also be an opportunity to check for unnecessary complexity. Most of the book A Philosophy on Software Design is about finding these red flags in code via the code review process (a core part of Viget’s development workflow.) I was inspired to consider some of those same red flags as things to look out for when reviewing product designs, for example:
- Shallow module: interface is complicated relative to the functionality it provides.
- Information leakage: same knowledge is used in multiple places
- Overexposure: accessing a commonly-used feature forces users to learn about other features that are rarely used.
Takeaway: Review product designs for simplicity’s sake. Remember, reducing complexity is good for users, too.
9. “Comments should describe things that aren’t obvious from the design.”
Dr. Ousterhout was referring to code comments, but this logic can also be applied to design annotations and ticket-writing. There are lots of ways to write tickets (and no one right way to do it), but a good rule of thumb is to describe/comment on only that which isn’t obvious from the design. If the ticket is 500 words long and repeats 99% of what’s in the design, that creates a ton of cognitive overhead for engineers, which should be avoided.
Takeaway: Be strategic in the contextual information you include when writing tickets for engineers. Comments, descriptions, and design annotations are helpful for things that aren’t self-evident, but add complexity for things that are.