Exploring the Design Space

In Choosing a Software Design Strategy I proposed that your understanding of the design space will determine what design strategies are appropriate for your project. That is, how much you know about the problem domain and solution space will determine how much design work is appropriate for your project. Rather than fussing over dogma, the power is clearly in your hands. If you feel uncomfortable with what you are capable of designing, then you need to further explore the design space! Otherwise, you are free to design in a way that is appropriate to your understanding of the system and a way that makes sense to your team be it Big Design Up Front or a more minimalistic design approach.

Personally I'm a visual person so having a graphical representation which shows how to think about what I know about the design space is extremely helpful to me. In this graphical representation, there is a real boundary which will eventually prevent me from exploring the infinitely large design space. This boundary is formed by things like time, budget, and schedule as well as thought stuff such as your team's training or overall knowledge and the existence of research or even existing technologies. For example, once I was involved with a project that required large amounts of data to be transferred from Australia to the United States in real-time with an aggressive deadline, on the order of tens of milliseconds. Crunching the numbers, we quickly realized that this was completely impossible with the existing telecommunications infrastructure. In fact, the only technology we could find which might promise this kind of performance was entangled quantum particles which are only today becoming a reality...sort of. The solution boundary in this case severely limited our ability to find a viable design. Sometimes you can move these real boundaries, for example by increasing the budget and schedule or hiring a consultant, but any system you design will come from your understanding of the area in the highlighted space shown below.



Another interesting thing about this representation is that it's actually parametric. The X and Y axes will tell you what you know, but your understanding of the problem you aim to solve and the solution you are using to solve it will change over time. It's also possible that you might not start at (0, 0) in every case. And the way you learn about the design is going to be different every time, rarely (if ever) taking the direct, efficient route to enlightenment. As time goes on, as you learn more about the problem and solution, you'll create a parametric curve, the shape of which will give you a pretty good idea of where your knowledge gaps might be. And thinking about design in this way exposes some interesting things about what you know, and what you might need to learn in order to make a satisficing design.



So if you have a design curve that starts off almost horizontal, it means that you know a lot about the problem but don't know very much about solutions. Teams with lots of specific domain knowledge might face a curve like this. Most of the projects I did with the US Navy started with a curve that looked like this. The problems the Navy was trying to solve were well understood and the teams were initially made up of veteran subject matter experts. One of my jobs then was to help understand how to solve these well understood problems using more recent advances in hardware and software.

A curve which starts off steep presents the exact opposite case. Here the team has plenty of knowledge about possible solutions but knows very little about the problem. This is the case with most software development teams. We're experts in building software and in most cases, when someone comes to us with a problem they want a software solution. The team's main focus will be on understanding requirements and then applying their software engineering knowledge in creating a solution. A great example of this scenario is web development shops who specialize in creating web applications for clients. For these teams, every solution will involve some kind of 3-tiered system, probably using one of a handful of languages the team is an expert in. Now it's just a matter of understanding the problem so they can iron out the specifics of the solution.



Most of the time your team is going to have a pretty good mix of knowledge, and as you work to complete the project you'll embark on a circuitous journey through the design space, eventually coming to a point where you'll feel comfortable moving forward with design and full scale development.

Your team will have some base knowledge at the start of the project. From there you'll start to explore requirements which might lead you to thinking of certain solutions. Of course any solution will involve trade-offs which will expose new problems to consider so it's back to the client to talk about the positives and negatives of one solution over another (quality attribute scenarios work great in this situation). As you explore these new problems, you'll gain new knowledge which will then help you learn even more about the solution. Throughout this journey you might create prototypes, architecture descriptions, sketches, or code stubs. Each of these things will serve as a communication aide for your team and clients and give you tangible evidence of your understanding of the design space.



The ultimate goal of this line of thinking is to figure out a better way to understand how to effectively explore the design space so you can more effectively reach a point when you have enough knowledge to be able to move forward with implementation. At some point, you'll feel comfortable with what you know and create an appropriately detailed design. Or maybe you'll just jump right into implementation. Exploration might take a few minutes or several weeks, all depending on what you already know about the problem and potential solutions, not to mention the size of the design space that needs exploring (more space implies more complexity and bigger systems). You might leave large swaths of the design space unexplored when you create your design or move onto implementation or you might explore everything fully. Regardless of your knowledge, it is important to realize that the amount of detail you use in your design and when you do that design work - the design strategy you choose - is an independent matter but your knowledge will limit your design capabilities.

The awesome part about thinking about design in this way is that even though you've moved on to a different phase of your project's lifecycle, your knowledge and understanding of the design space will not cease. You'll continue to learn more about the problem and solution with each step of implementation until the project ends. And by the end you will have the most complete understanding of the problem and solution yet. Of course, this will also be the time when this understanding is least helpful to you since the project is over! The essential key then is to apply methods which help you to quickly and efficiently understand when enough is enough so you can create useful plans, organize your team, and begin implementation with confidence that you will succeed.

Popular posts from this blog

Dealing with Constraints in Software Architecture Design

Architectural Drivers: Building Blocks for Decision Making

Managing Multiple Ruby Versions with uru on Windows