2024 Public Training Schedule
November 18 – 21, 2024 – Agile Analysis and Design Patterns
Half-Day Sessions
December 9 – 12, 2024 – Agile Analysis and Design Patterns
Half-Day Sessions
(c) 2024 To Be Agile
Of course, it always turns out that the biggest risks are the ones we are unaware of. “What you don’t know can’t hurt you” is a myth. It’s the things that we don’t know about that can hurt us the worst. This is why we strive to reduce unknowns and dependencies. There are typically a lot of unknowns on a software project, and we have to get comfortable with uncertainty.
I have developed some techniques for managing risks. First of all, I like to make things visible. I list my dependencies and the major things that could go wrong to keep an eye on them throughout the project and ensure I stay on track. I look for ways of encapsulating issues in code so I can defer on them and deal with them later without paying a huge price. If I can hide a service behind a well-defined interface, I don’t have to implement that service immediately. It’s taken me a lifetime to figure out the important things to keep track of on software projects.
One thing I’ve learned from my experience is that it’s easier to figure out a problem when I’m in the midst of it rather than trying to figure it out from afar. What I mean by ‘from afar’ is when we are planning or thinking about doing some work rather than when we are doing the work. I find that while I’m coding, I can do my best designs. I think that doing an upfront design is fallacious most of the time. It’s more difficult and less accurate to imagine doing the work than doing it.
Because of this, I find it’s more effective to figure many things out as I go, which means I go into iteration with unknowns. Many times these unknowns work themselves out, so they don’t ever become issues, but there are times when they don’t, and I’m forced to deal with them. Perhaps there is a service that I need, but I’m not sure if there is a framework that will do it for me, or perhaps I have an unknown implementation detail that I have to work out.
I take all that into iteration with me, and when I bump up against those unknowns and can’t go any further, I create a little mini time-box. I say that for the next hour or day or whatever, I will research the following things, and at the end of the time box, I see how I did. I asked myself if I had resolved my issues and answered my questions. Do I have new questions? Can I move forward, or do I have to create another mini time-box to answer new questions?
I find that it is more efficient to take these issues into iteration with me than to figure them out upfront because I don’t know which issues are important and which are unimportant. So I end up with a longer list of issues I must resolve.
Often, the issues that I have are a result of missing information. Either I don’t understand how a feature is supposed to work, or I have unresolved implementation issues that must be dealt with. When I first identify what I need to know, I can clearly define a strategy for finding it out. From there, I iterate.
Emergent design is about letting a design emerge by paying attention to what tests need from code and what code needs from tests. It’s an advanced technique, but it can be magic when it works well. When doing emergent design, we start simple and iteratively build features. The end result for me is often much better than what I had imagined, so it is my preferred way of building software.
Previous Post: « Identify Areas of Risk
Next Post: Build the Smallest Piece that Shows Value »