So I recently mentioned building things 'well and in context'. It occurred to me after I wrote that, that someone would assume my intention was to suggest that you overbuild software in order to enable reuse. I would recommend against this.
As software developers we get paid to deliver solutions. That is, we get paid to put software into production so it can be used to solve a problem. It might seem like we're being paid to create code, deployment is someone else's problem, but I assure you that is not the case. Eventually time catches up with us all, and in the final evaluation, if we have not delivered code to production we will be downsized.
Time and time again I've seen teams of developers slave away to build a system only to have it shelved. The developers usually survive this and move on to other projects. Someone else takes the hit. Eventually though, an organization will falter and collapse if nothing ever gets delivered. An organization that is paying attention will shed the weight of a dysfunctional development team before that collapse ever happens. Sure, they might do it by re-assigning the developers to COBOL maintenance, but they will solve the problem. Of course if you are a contracted resource, you simply get an email telling you to not show up on Monday, m'kay.
Anyway, I digress. When I talk about building things well and in context, I'm talking about staying focused and creating only the code necessary to solve the problem at hand. That code should be well crafted. It should have a complete set of unit test, integration tests as necessary, and of course, acceptance tests. Everything should be well named, formatted, and clean. But it shouldn't do anything other than what it was intended to do.
This is a mini-blog. I'm working to find a compromise between a tweet and a lengthy essay. I find it difficult to complete longer documents because of an obsession with perfection. So this little experiment is to see if I can create a blog of mini articles. Herein I will talk about many technical things generally related to software development and Agile practices.
31 March 2017
29 March 2017
A Technique for Practicing TDD in Two Steps
So there are a ton of kata's out there in the world. There are practice exercises, and there are tutorials. I think a lot of them are really nifty and I've enjoyed working through many of them. However, I think rote memorization of katas is not really learning TDD so much as it is learning a technique, developing muscle memory, and practicing. For example, Uncle Bob's Bowling Kata isn't really about TDD so much as it is about Design Sense via method extraction.
I don't know when I came up with this technique for learning TDD, it just sorta happened. I have found it to be one of the most challenging things I've ever done, and once I mastered it I stopped struggling to do TDD.
Here is an outline of this learning technique.
I don't know when I came up with this technique for learning TDD, it just sorta happened. I have found it to be one of the most challenging things I've ever done, and once I mastered it I stopped struggling to do TDD.
Here is an outline of this learning technique.
- Find a small problem to solve. I use Project Euler as source of inspiration.
- Attempt to solve the problem via TDD without thinking ahead.
Thats all there is to it. Of course there is a catch. You can't think ahead. That is a lot harder than it seems. Even for simple stuff, we often jump to the end and think about the final result. In so doing we exert a lot of influence on our implementation. The preconceived notions we take into our first test can limit our imagination for how to solve any given problem and they most assuredly cause our TDD to become clumsy and mechanical.
So try this out. The first problem listed in the archives of Project Euler is called Multiples of 3 and 5. The objective is to sum all numbers that are multiples of 3 or 5 within a specified range. [Note: I read this question as implying a lower bound, you may choose to ignore that if you like] The example given is for numbers less than ten, the result is 23 (3 + 5 +6 + 9). So how would we write the code for that.
This problem is so simple that most of us have figured it out in our heads already. Something like, we'll I'd write a loop from zero to 10 and check each number for divisibility by 3 and 5 using mod and then put those numbers in a list and add them up.
OK, sure. Now test drive that.
But that wasn't the point of our game. Test drive that without thinking ahead. Don't think about loops, don't think about how you'd construct the list of numbers to be added at all. Think about how you'd test that your function did the right thing without thinking about the content of the function.
So your first test might be something like this;
assert_equals( 23, f(0,10) )
And to make that true you'd write
def f(min, max):
return 23
Now what do you do next? How about this;
assert_equals( 33, f(0,11) )
And to make that pass you might write;
def f(min, max):
if max == 10:
return 23
if max == 11:
return 33
But this isn't a general solution, so you'd add more tests and your code might evolve to look like this;
def f(min, max):
numbers = []
num = 0
while num < max:
if num % 3 == 0 or num % 5 == 0:
numbers.append(num)
num += 1
result = 0
for num in numbers:
result += num
return result
And eventually deal with the lower bound..
def f(min, max):
numbers = []
num = min
while num < max:
if num % 3 == 0 or num % 5 == 0:
numbers.append(num)
num += 1
result = 0
for num in numbers:
result += num
return result
...and hopefully after some refactoring you'd arrive at something like this;
def f(min, max):
def f(min, max):
return sum([number for number in range(min, max) if number % 3 == 0 or number % 5 == 0])
So the point of all this isn't the result, or the intermediate steps, its about developing the patience and self control to step through any problem in these tiny increments without anticipating the next step. A lot of practitioners might have started much closer to my first draft of the generalized solution than they would like to admit. If you practice this technique however, you will find yourself taking smaller steps forward, making fewer and more easily recovered mistakes, and developing simpler designs.
27 March 2017
Staying in Context
So I've always had issues staying in context. That is, when I take a break from what I'm doing I sometimes forget what I was doing and then, when I return, I have to sort of reboot whatever it was. This has been particularly difficult after a long break, like a two week vacation or sometimes even a four day weekend. So over the years I've developed a couple of techniques to keep me sharp and on task when I return.
First, I try not to leave anything undone. If I'm preparing for a trip or some time off I work very hard to make sure I leave my work in a stable and understandable state. This has lead to a few long nights prior to departure, but it always pays off. Once, about 17 years ago, I worked straight through the night to finish up my task list before going on a two week vacation. My wife thought I was nuts, but when we returned from vacation I was able to jump right back into work like I hadn't been gone at all. This was simply because my todo list was empty when I left. There was no context to pick up.
Now obviously that approach isn't going to work for everyone. First, who really wants to stay up all night working before a vacation. Second, sometimes the todo list is much too long to knock it down the night before you go someplace. But if you can manage this arrangement, its the number one way to come back ready to go.
So what about those times when I can't get the todo list done? Well, start with taking notes. I use Trello and Evernote to keep myself organized. I have 73 Trello boards at the moment and hundreds of notes in Evernote. Thats a lot of stuff to keep organized, but the advantage I have (usually) is I can come back to something I haven't touched in months and take off pretty close to where I started. It isn't a perfect system, but it usually works out.
Some of the boards I use most often are my Personal ToDo list, my Client ToDo list (I have one for each client), my Client Priorities list (again, one for each client), my Home Projects list, and anywhere from one to three boards for each software project. It sounds sort of ridiculous, but because I have all those boards, and I keep them up to date, I can walk away at any time and come back to where I was. When I get back, all I do is open up the board and look at the last card I was working on. That is usually enough to get me pointed in the right direction.
I use Evernote to keep track of the details. Trello is great, but it has its limits, especially search-ability. So I keep notes on the things I'm working on in Evernote and that helps me reset my context quickly. I can also tag things and lump things together in notebooks. It gives me a leg up on staying organized. I also like the fact that I can run it on anything with a web-browser.
Beyond the electronic stuff I have one last trick up my sleeve. Post-Its! I work from home and I get interrupted by stuff on occasion; the doorbell, dog needs to go out, Orkin guy shows up to spray for bugs, whatever. Those little interruptions cause me to lose focus and sometimes that can be very disruptive. So I keep a pad of Post-Its next to my keyboard, I can leave myself a little note about what I was doing. Simple, two or three word reminders. So if I have to answer the door I might just write down 'Plan Foo App' and drop the note on my keyboard. When I come back I know what I was doing. Its nothing more special than that. Before post-its were so easy to get I used printer paper and just wrote on that. It doesn't have to be post-its, anything you can write on will work.
OK, so why did we go through all this? Well, I'm showing you what I do to stay in context. All of these things help keep me in context for everything I do. When I come to work, I'm in context for what I'm doing. When I go out with my family I'm in context there too. And in keeping myself in context I am much more effective and focused.
Why is that important? Well, for one thing, I get paid to deliver. Weather you like it or not, you probably do too. If I take too much time to deliver, or I deliver the wrong thing, I risk losing my job. So its important that I stay focused on what the client wants. Thats hard when you have more than one client or project to deal with. Its even harder if you have a busy personal life. So I use all these tools to optimize the performance.
There is one last thing about staying in context that I think is really important. When you are in context with what you are doing, you tend to do a better job. You make better choices about what you are doing presently in order to be more effective overall. Paying close attention to what you are doing now so that you have greater success in the long run pays off big. In practical terms, building one module of code well, and in context, today, will pay dividends later when you go to reuse it.
First, I try not to leave anything undone. If I'm preparing for a trip or some time off I work very hard to make sure I leave my work in a stable and understandable state. This has lead to a few long nights prior to departure, but it always pays off. Once, about 17 years ago, I worked straight through the night to finish up my task list before going on a two week vacation. My wife thought I was nuts, but when we returned from vacation I was able to jump right back into work like I hadn't been gone at all. This was simply because my todo list was empty when I left. There was no context to pick up.
Now obviously that approach isn't going to work for everyone. First, who really wants to stay up all night working before a vacation. Second, sometimes the todo list is much too long to knock it down the night before you go someplace. But if you can manage this arrangement, its the number one way to come back ready to go.
So what about those times when I can't get the todo list done? Well, start with taking notes. I use Trello and Evernote to keep myself organized. I have 73 Trello boards at the moment and hundreds of notes in Evernote. Thats a lot of stuff to keep organized, but the advantage I have (usually) is I can come back to something I haven't touched in months and take off pretty close to where I started. It isn't a perfect system, but it usually works out.
Some of the boards I use most often are my Personal ToDo list, my Client ToDo list (I have one for each client), my Client Priorities list (again, one for each client), my Home Projects list, and anywhere from one to three boards for each software project. It sounds sort of ridiculous, but because I have all those boards, and I keep them up to date, I can walk away at any time and come back to where I was. When I get back, all I do is open up the board and look at the last card I was working on. That is usually enough to get me pointed in the right direction.
I use Evernote to keep track of the details. Trello is great, but it has its limits, especially search-ability. So I keep notes on the things I'm working on in Evernote and that helps me reset my context quickly. I can also tag things and lump things together in notebooks. It gives me a leg up on staying organized. I also like the fact that I can run it on anything with a web-browser.
Beyond the electronic stuff I have one last trick up my sleeve. Post-Its! I work from home and I get interrupted by stuff on occasion; the doorbell, dog needs to go out, Orkin guy shows up to spray for bugs, whatever. Those little interruptions cause me to lose focus and sometimes that can be very disruptive. So I keep a pad of Post-Its next to my keyboard, I can leave myself a little note about what I was doing. Simple, two or three word reminders. So if I have to answer the door I might just write down 'Plan Foo App' and drop the note on my keyboard. When I come back I know what I was doing. Its nothing more special than that. Before post-its were so easy to get I used printer paper and just wrote on that. It doesn't have to be post-its, anything you can write on will work.
OK, so why did we go through all this? Well, I'm showing you what I do to stay in context. All of these things help keep me in context for everything I do. When I come to work, I'm in context for what I'm doing. When I go out with my family I'm in context there too. And in keeping myself in context I am much more effective and focused.
Why is that important? Well, for one thing, I get paid to deliver. Weather you like it or not, you probably do too. If I take too much time to deliver, or I deliver the wrong thing, I risk losing my job. So its important that I stay focused on what the client wants. Thats hard when you have more than one client or project to deal with. Its even harder if you have a busy personal life. So I use all these tools to optimize the performance.
There is one last thing about staying in context that I think is really important. When you are in context with what you are doing, you tend to do a better job. You make better choices about what you are doing presently in order to be more effective overall. Paying close attention to what you are doing now so that you have greater success in the long run pays off big. In practical terms, building one module of code well, and in context, today, will pay dividends later when you go to reuse it.
24 March 2017
Hesitation is Failure
About 14 years ago a very sage friend of mine said to me 'Hesitation is failure'. At the time I didn't really understand what he meant but what I've come to realize is that if you sit around thinking about a problem rather than trying to solve the problem, you are hesitating. So why is that failure?
A different friend told me a story about his experience at West Point that I think illustrates the point. It was during the first week of leadership training when my friend was assigned a squad. The platoon leader had all of the squads muster in a common area. Surrounding them were a number of 55 gallon oil drums.
When the squads were mustered the instructors, without explanation, started shouting orders to "move" and "seek cover" while others set off explosives in the oil drums. It was total chaos as a half dozen instructors screamed at the squads and the squad leaders tried to figure out what to do.
As my friend tells it, he instructed his squad to run away from the common area and to rally at a point a few dozen meters away. His squad followed their instructions and he passed the test. Other squad leaders however had frozen in the confusion. It was gently explained that they had succeeded in killing their entire squad.
What was the point? Well, the squad leaders that hesitated to issue orders and respond to the situation had failed, resulting in hypothetical death and dismemberment.
Obviously in software the consequences of hesitation are far less significant. That said, when we hesitate we fail. So it is much better to take action, any action, than it is to contemplate and analyze and consider. I guess this relates to my statements about not needing a card for every single thing. But it also has to do with decision velocity. Everything we do has some amount of consideration, so I'm not suggesting that we don't think a least a little bit about what we're going to do. But I am pointing at getting stuck in analysis paralysis. When we are stuck there, we are failing.
So how does this relate to daily team room operations and projects? Well, for me anyway, when given a card to work on, just dive right in. When you have a question about how something works, don't sit around speculating; read the source code. It is perfectly reasonable to take a risk in your development environment, very few things we do can have catastrophic results, and when they do, well, we can guard against them. But the hesitation, the over analyzing, the hand wringing, that is what ultimately kills our forward momentum. So, my suggestion is, stop over thinking things and just give it a try. Get things done by getting things done, rather than over considering weather you should do things.
A different friend told me a story about his experience at West Point that I think illustrates the point. It was during the first week of leadership training when my friend was assigned a squad. The platoon leader had all of the squads muster in a common area. Surrounding them were a number of 55 gallon oil drums.
When the squads were mustered the instructors, without explanation, started shouting orders to "move" and "seek cover" while others set off explosives in the oil drums. It was total chaos as a half dozen instructors screamed at the squads and the squad leaders tried to figure out what to do.
As my friend tells it, he instructed his squad to run away from the common area and to rally at a point a few dozen meters away. His squad followed their instructions and he passed the test. Other squad leaders however had frozen in the confusion. It was gently explained that they had succeeded in killing their entire squad.
What was the point? Well, the squad leaders that hesitated to issue orders and respond to the situation had failed, resulting in hypothetical death and dismemberment.
Obviously in software the consequences of hesitation are far less significant. That said, when we hesitate we fail. So it is much better to take action, any action, than it is to contemplate and analyze and consider. I guess this relates to my statements about not needing a card for every single thing. But it also has to do with decision velocity. Everything we do has some amount of consideration, so I'm not suggesting that we don't think a least a little bit about what we're going to do. But I am pointing at getting stuck in analysis paralysis. When we are stuck there, we are failing.
So how does this relate to daily team room operations and projects? Well, for me anyway, when given a card to work on, just dive right in. When you have a question about how something works, don't sit around speculating; read the source code. It is perfectly reasonable to take a risk in your development environment, very few things we do can have catastrophic results, and when they do, well, we can guard against them. But the hesitation, the over analyzing, the hand wringing, that is what ultimately kills our forward momentum. So, my suggestion is, stop over thinking things and just give it a try. Get things done by getting things done, rather than over considering weather you should do things.
22 March 2017
The Essence of TDD
I love TDD. I first heard about it in 2003 while working at the phone company. My supervisor brought me an article from Info-Week on the subject. I dismissed it. I thought, how can I possibly write a test for code that I have not designed? How could I possibly know what a function will return given any input, if I have not written it? I clearly didn't get it.
Fast forward to August of 2004 when I took a new job with a consulting firm in Ohio. I was hired and sent to a two week boot camp experience with one of their most senior consultants where I learned about how they develop software. On the list of things to learn, and the one I struggled with the most, was TDD. Mostly by force I learned how to do it. It was awful and I thought, I'm going to ditch this practice as soon as I get out of here.
But then something strange happened. After the bootcamp I was put on a team and asked to clean up after another consultant. Apparently one of the guys on the team felt like I did, that TDD was nuts, and hadn't done it. Worse though, he hadn't done TAD (Test After Development). So we had some pretty hefty swaths of code with no test coverage at all. I spent about three weeks cleaning up his mess. All the while thinking that getting test coverage here was a good idea, and I was glad I didn't have to do that TDD thing. When I got done I had a rude surprise waiting for me. I thought I was going off to another project, but instead I was given work on this team. Work that involved developing new software that had to be TDD'd.
The tech lead on the project was keeping a pretty close eye on me, as well as my mentor who happened to be on the project. I was called repeatedly for not formatting my code correctly and it was embarrassing. But I was smart enough to commit my tests with the my code, and as a consequence I tried really hard to use TDD. So in those next three weeks I forced myself to use TDD as much as I could. I learned to love it.
For several years after this experience I travelled the country writing code for various organizations and using TDD as a technique. I was very pleased with the outcome and I became very proficient with the tooling and the practice. But when asked why I was using this technique (I was surrounded by nay-sayers) my only answer was, to ensure that the code is throughly tested, and to provide a suite of regression tests to prevent accidental breakage. Later I evolved my answer to include mention of Continuous Integration and tried to explain how we could use TDD and CI to do automatic reconnaissance of issues caused by changes.
Those are all great answers to why we do TDD, but I don't think they hit on the essence of TDD. The real deep purpose of TDD in my mind is this, we use TDD to figure out what needs to be done, all those other things are happy consequences of having done TDD.
Here is how that works. Given a problem statement like, I need code that finds the difference between two object graphs, how do we design/develop a solution? No matter what technique we are using BDUF, TDD, or something in between, we have to ask a bunch of questions. Here are some questions we might ask;
Fast forward to August of 2004 when I took a new job with a consulting firm in Ohio. I was hired and sent to a two week boot camp experience with one of their most senior consultants where I learned about how they develop software. On the list of things to learn, and the one I struggled with the most, was TDD. Mostly by force I learned how to do it. It was awful and I thought, I'm going to ditch this practice as soon as I get out of here.
But then something strange happened. After the bootcamp I was put on a team and asked to clean up after another consultant. Apparently one of the guys on the team felt like I did, that TDD was nuts, and hadn't done it. Worse though, he hadn't done TAD (Test After Development). So we had some pretty hefty swaths of code with no test coverage at all. I spent about three weeks cleaning up his mess. All the while thinking that getting test coverage here was a good idea, and I was glad I didn't have to do that TDD thing. When I got done I had a rude surprise waiting for me. I thought I was going off to another project, but instead I was given work on this team. Work that involved developing new software that had to be TDD'd.
The tech lead on the project was keeping a pretty close eye on me, as well as my mentor who happened to be on the project. I was called repeatedly for not formatting my code correctly and it was embarrassing. But I was smart enough to commit my tests with the my code, and as a consequence I tried really hard to use TDD. So in those next three weeks I forced myself to use TDD as much as I could. I learned to love it.
For several years after this experience I travelled the country writing code for various organizations and using TDD as a technique. I was very pleased with the outcome and I became very proficient with the tooling and the practice. But when asked why I was using this technique (I was surrounded by nay-sayers) my only answer was, to ensure that the code is throughly tested, and to provide a suite of regression tests to prevent accidental breakage. Later I evolved my answer to include mention of Continuous Integration and tried to explain how we could use TDD and CI to do automatic reconnaissance of issues caused by changes.
Those are all great answers to why we do TDD, but I don't think they hit on the essence of TDD. The real deep purpose of TDD in my mind is this, we use TDD to figure out what needs to be done, all those other things are happy consequences of having done TDD.
Here is how that works. Given a problem statement like, I need code that finds the difference between two object graphs, how do we design/develop a solution? No matter what technique we are using BDUF, TDD, or something in between, we have to ask a bunch of questions. Here are some questions we might ask;
- Are we comparing the object graphs by type and value, or only one or the other?
- What constitutes a difference? Is 1 == 1.0?
- What should the output of the difference look like?
- Who is the 'source' of the difference? (left argument or right)
Of course there are dozens more questions that could be asked, but you get the point. So, each one of those questions can become a test. Better still, as we poke around the edges of each question we can come up with more questions. We can keep writing code until all the questions have answers and the answers are verified by the code. So, in essence, we are figuring out what what to do by writing tests. Everything else is just gravy.
Once I saw this I had a new appreciation for TDD and what it meant. It radically changed the way I create software and even think about problem solving. It also helped me develop new skills and techniques for approaching problems. It got me into a lot more conversations with my product owner too.
20 March 2017
You Don't Need a Card for That
I have observed a behavior in some people that suggests that cannot act independently. That is, they need to be told what to do or nothing will happen. Simultaneously the very same people would complain loudly if that there was nothing to do if you didn't provide them some guidance. I've been trying to figure this out for some time as I've seen it happening for years in all corners of my life.
I don't think the people who do this are aware of how it is perceived. From the outside it make them look like order takers. They may be exceptionally competent at their jobs and technically proficient, but they lack an internal driving force to just get things done without being told to do so. Those people are exactly the people I don't really want to deal with.
So in considering why these people act this way I've arrived at the following observations. Some of these people are looking for credit. They want to account for every second of their time if possible, so that when questioned they can say 'See my list of Cards, that is what I've been doing'. Some of these people fear retribution for not following a plan, there are trying to avoid hearing the question 'Why did you do that?' or the statement 'Stay on task'. Lastly, and very cynically, there are some who are not deeply engaged in what they are doing, they cannot remember from moment to moment what their purpose is or why they are driving to a goal; these people need the card so they can be reminded of what to do.
None of these approaches are overly effective. When developing software or delivering projects there is a fair amount of 'Doing the right thing' that needs to occur. We talk about the Boy Scout Principle with respect to code. Further, we claim to be 'Looking out for the customer's best interest'. Do we really? Or do we do what we're told and occasionally clean up when we make a mess.
I submit for your consideration that You Don't Need a Card for That applies more often than not. If you are given a bit of work to do and notice an issue like bad variable names, just clean them up, don't ask for a card. If you find a clunky implementation, just fix it while you are there. The administrative overhead of creating a card, scheduling the card, balancing the backlog, code review, acceptance process, and deployment greatly outweigh the value of just getting something done.
This, of course, leads to a different problem. How do I know if I should Just Do It, or create a card. Here is a simple metric. If you believe the work to deal with an issue is less than the time to run through the process of card creation to card delivery, just do it. If the change has a net benefit disproportionally greater than the effort and the same time as the process or maybe even a little more, just do it. Ultimately the goal of software development is delivering the product, not tracking the cards.
I don't think the people who do this are aware of how it is perceived. From the outside it make them look like order takers. They may be exceptionally competent at their jobs and technically proficient, but they lack an internal driving force to just get things done without being told to do so. Those people are exactly the people I don't really want to deal with.
So in considering why these people act this way I've arrived at the following observations. Some of these people are looking for credit. They want to account for every second of their time if possible, so that when questioned they can say 'See my list of Cards, that is what I've been doing'. Some of these people fear retribution for not following a plan, there are trying to avoid hearing the question 'Why did you do that?' or the statement 'Stay on task'. Lastly, and very cynically, there are some who are not deeply engaged in what they are doing, they cannot remember from moment to moment what their purpose is or why they are driving to a goal; these people need the card so they can be reminded of what to do.
None of these approaches are overly effective. When developing software or delivering projects there is a fair amount of 'Doing the right thing' that needs to occur. We talk about the Boy Scout Principle with respect to code. Further, we claim to be 'Looking out for the customer's best interest'. Do we really? Or do we do what we're told and occasionally clean up when we make a mess.
I submit for your consideration that You Don't Need a Card for That applies more often than not. If you are given a bit of work to do and notice an issue like bad variable names, just clean them up, don't ask for a card. If you find a clunky implementation, just fix it while you are there. The administrative overhead of creating a card, scheduling the card, balancing the backlog, code review, acceptance process, and deployment greatly outweigh the value of just getting something done.
This, of course, leads to a different problem. How do I know if I should Just Do It, or create a card. Here is a simple metric. If you believe the work to deal with an issue is less than the time to run through the process of card creation to card delivery, just do it. If the change has a net benefit disproportionally greater than the effort and the same time as the process or maybe even a little more, just do it. Ultimately the goal of software development is delivering the product, not tracking the cards.
17 March 2017
Abandon Your Process and Think
I've been in the software game for a long time, something like 25 years professionally. Through that time I've used a number of processes and techniques for planning, designing, and delivering software. I've even invented a few of my own. Every technique I've used has had its good parts and its bad parts, but when it comes to actually delivering Agile/Lean approaches seem to work best. That said, there are still issues with these techniques.
Consider that you are relying on your process to think for you.
I don't want to disparage anyone or any process in this conversation, but in order to explain I'll need to talk about some specific practices that I've seen. One of my favorite whipping boys is the Definition of Ready. Time and time I again I see teams institute a Definition of Ready and then watched as the lights go out. The developers seem to stop thinking about the context of their work and become hyper focused on the card at hand once they have completed the Definition of Ready. Its as if the process has turned off a part of their brain.
Defect triage is another process that seems to turn peoples brains off. An issue that is trivial to fix, say a log file size configuration becomes a full defect on a card wall that is timed, measured, and reviewed when the actual work to correct the problem might take two or three minutes to resolve. The process has taken over completely in this case.
I remember the old days (2004) when we just got things done. Most of the cards we had in our team room had a few words on them and we just had a quick discussion about what needed to get done, then we did it. There was no Definition of Ready and the Definition of Done was one line line, 'Does the Product Owner approve?'. When we found issues or problems we just fixed them. If someone outside the team found an issue we created a card, took our lumps for having a defect, and then we just fixed it. Things moved pretty fast back then.
I think we were so effective because we were always thinking. The process was seen as a constraint and therefore kept very intentionally light. Good intent and attentiveness was all we needed to develop good software. What I see today is too much process, to much adherence to process, and a blindness of process obsessed coding zombies.
The irony is that many of the people I see behaving this way are asking for more autonomy. Their response to having that autonomy is more process that they then blindly follow. I'm not sure if the processes they create are a expression of their commitment to the autonomy; as if process is what was asked for, or If process is a comforting respite from thinking. I cynically presume the later.
Ultimately I believe that having clarity about the objectives of our work is what matters most. The processes that we use should remain ephemeral and be adapted rapidly to the conditions of the work that we endeavor to complete. If a process is not working, don't try to force it, throw it away and think about the problem without the constraints. If it turns out that a process is the right answer to a problem, then apply the process to that problem and move on, but don't assume that the process is universally applicable, and by all means, don't force the process onto everyone and everything.
Consider that you are relying on your process to think for you.
I don't want to disparage anyone or any process in this conversation, but in order to explain I'll need to talk about some specific practices that I've seen. One of my favorite whipping boys is the Definition of Ready. Time and time I again I see teams institute a Definition of Ready and then watched as the lights go out. The developers seem to stop thinking about the context of their work and become hyper focused on the card at hand once they have completed the Definition of Ready. Its as if the process has turned off a part of their brain.
Defect triage is another process that seems to turn peoples brains off. An issue that is trivial to fix, say a log file size configuration becomes a full defect on a card wall that is timed, measured, and reviewed when the actual work to correct the problem might take two or three minutes to resolve. The process has taken over completely in this case.
I remember the old days (2004) when we just got things done. Most of the cards we had in our team room had a few words on them and we just had a quick discussion about what needed to get done, then we did it. There was no Definition of Ready and the Definition of Done was one line line, 'Does the Product Owner approve?'. When we found issues or problems we just fixed them. If someone outside the team found an issue we created a card, took our lumps for having a defect, and then we just fixed it. Things moved pretty fast back then.
I think we were so effective because we were always thinking. The process was seen as a constraint and therefore kept very intentionally light. Good intent and attentiveness was all we needed to develop good software. What I see today is too much process, to much adherence to process, and a blindness of process obsessed coding zombies.
The irony is that many of the people I see behaving this way are asking for more autonomy. Their response to having that autonomy is more process that they then blindly follow. I'm not sure if the processes they create are a expression of their commitment to the autonomy; as if process is what was asked for, or If process is a comforting respite from thinking. I cynically presume the later.
Ultimately I believe that having clarity about the objectives of our work is what matters most. The processes that we use should remain ephemeral and be adapted rapidly to the conditions of the work that we endeavor to complete. If a process is not working, don't try to force it, throw it away and think about the problem without the constraints. If it turns out that a process is the right answer to a problem, then apply the process to that problem and move on, but don't assume that the process is universally applicable, and by all means, don't force the process onto everyone and everything.
15 March 2017
Fo5
So this is just a quick post about Fist of Five. We use Fo5 all the time to determine if we have consensus or have confidence in something in our team. Our problem is that we are mostly distributed. So this makes the process of counting up scores hard, in particular if a number of people are in the same place. We've been looking for better ways to do this.
Today (8 Mar 2017) I went looking for a solution to this issue. I found this cool little application. It solves most of the problem I think. We still have an issue where we have a room full of people who are not on their own machines, how will they vote. For now, we will have the room vote and if they don't agree with the rest of the team we'll just trigger the conversation. Still, I think this is better than nothing, and better than counting hands through a web-cam.
Today (8 Mar 2017) I went looking for a solution to this issue. I found this cool little application. It solves most of the problem I think. We still have an issue where we have a room full of people who are not on their own machines, how will they vote. For now, we will have the room vote and if they don't agree with the rest of the team we'll just trigger the conversation. Still, I think this is better than nothing, and better than counting hands through a web-cam.
13 March 2017
Size Matters
A lot of people seem to think that size is unimportant. In the small this might be true, but in the large scheme it becomes important quickly.
When I say size, I'm talking about sizing work. In an age of ever shrinking project budgets and organization has limited funds to make choices with. No matter how you plan your work, you need to consider the initial and ongoing costs of any endeavor. You simply cannot do that without a size.
A number of people have suggested that we should just allocate money to an effort and get what we get from the money. For example, if I have a vision of a solution that will theoretically yield $1M in business value and I allocate $100k to a solution (1%) I can, in theory, build part or all of a solution to the $1M question. There are a lot of assumptions there, but go with it, assume its possible. We find ourselves asking, how did I get my $100k? From what pile of money did it come? How can I be sure that money will still be there when I start the effort? Do I cut the tail at $60 if I've realized 80% of the expected yield?
All great questions and I wish you the best of luck in answering them. But the reality is that most organizations aren't prepared for this conversation. They may never be ready to answer those questions. What is more realistic is that an organization allocates some amount of money for projects, say $10M for the year, picks the hottest topics off their planning sheet and divvy the money between them. In order to do that you need to know roughly how big each one is. If you can't see how big things are you can't make good choices in this situation.
So, size really does matter.
When I say size, I'm talking about sizing work. In an age of ever shrinking project budgets and organization has limited funds to make choices with. No matter how you plan your work, you need to consider the initial and ongoing costs of any endeavor. You simply cannot do that without a size.
A number of people have suggested that we should just allocate money to an effort and get what we get from the money. For example, if I have a vision of a solution that will theoretically yield $1M in business value and I allocate $100k to a solution (1%) I can, in theory, build part or all of a solution to the $1M question. There are a lot of assumptions there, but go with it, assume its possible. We find ourselves asking, how did I get my $100k? From what pile of money did it come? How can I be sure that money will still be there when I start the effort? Do I cut the tail at $60 if I've realized 80% of the expected yield?
All great questions and I wish you the best of luck in answering them. But the reality is that most organizations aren't prepared for this conversation. They may never be ready to answer those questions. What is more realistic is that an organization allocates some amount of money for projects, say $10M for the year, picks the hottest topics off their planning sheet and divvy the money between them. In order to do that you need to know roughly how big each one is. If you can't see how big things are you can't make good choices in this situation.
So, size really does matter.
10 March 2017
Better Product Ownership
In many organizations I see the Product Owner's duties relegated to super-clerk. A person who takes pre-cooked ideas and translates them into story cards. Their job becomes a drudgery of translate and publish. I find this to be most dissatisfying. Rather, a PO should collaborate with stakeholders to find a mechanism to solve a problem. The PO is the creative engine that defines the solution. That is exciting. That would get you out of bed in the morning for sure.
The process of converting that vision into a specification of work is an impediment to the product owners role. There is an excess of mechanical work. Create Card -> Validate that it meets the INVEST Criteria -> Map that story to a release plan -> Explain the vision to the developers -> Verify the result -> Demonstrate the Result -> Wait for deployment. That is a long arduous road to travel. It requires patience. It requires meticulous planning and attention to detail. And frankly I find much of it boring.
I think a better organization of work would be to have the Product Owner focus on Creating Cards and Defining Acceptance Criteria and Accepting Completed Work. All the mechanics should be delegated to someone else. The PO needs a creative environment free from the chores of manipulating card wall.
The process of converting that vision into a specification of work is an impediment to the product owners role. There is an excess of mechanical work. Create Card -> Validate that it meets the INVEST Criteria -> Map that story to a release plan -> Explain the vision to the developers -> Verify the result -> Demonstrate the Result -> Wait for deployment. That is a long arduous road to travel. It requires patience. It requires meticulous planning and attention to detail. And frankly I find much of it boring.
I think a better organization of work would be to have the Product Owner focus on Creating Cards and Defining Acceptance Criteria and Accepting Completed Work. All the mechanics should be delegated to someone else. The PO needs a creative environment free from the chores of manipulating card wall.
07 March 2017
Architect is a specialization of Product Owner
So I've been thinking about the role of Architect. First, there is an argument that we don't need architects; I disagree. For a single small project, architecture is reasonably compact and can probably handled by one or more team members to good effect. For a handful of similar applications we might even get away with establishing a pattern and repeating it and calling that architecture. But when we get to a larger scheme of applications with a diversity of purposes, someone has to keep the train on the tracks. That person is an Architect.
There are, at minimum, 7 aspects of architecture that need attention. But applying these across an entire enterprise uniformly is difficult to do organically. Much as I wish it were not true, someone has to make the choices about how a system will be maintained, how do we manage configuration, what systems interact with each other indirectly, and what constraints should be applied to all systems.
For example, all systems will use OAuth2 backed by the Azure platform could be a valid Architectural Choice. Each process in the system will interact via an Event Bus could be another. I could go on with dozens more examples, but the point is, many of these choices would be different on a per application basis when observed in isolation.
So I put forth the notion that an Architect is a specialization of Product Owner. A person with technical skills who understands both the economics of software development, the human aspects of organizational growth and stability, and the technical tradeoffs among the array of technologies available. Beyond that, their skills parallel those of a product owner.
An architect needs to solicit the business for information about what needs to be true. Understand those constraints and find technological solutions to them. All the while, an architect must be conscious of the organizations ability to achieve and maintain those objectives, both financially and practically. For example, if an Architect specified a technology outside the reach of the developers technical acumen without a plan for training and sufficient time for experimentation by the team, he or she would be failing. Similarly, if the revenue stream is too small to sustain a multi-million dollar installation of technology, the architect would likewise be failing. Additionally, an Architect should be looking at the long term impact of technology choices including, operating cost, license and maintenance fees, availability of hirable workforce, availability of training and support, and general applicability to domain problem solving.
This is just a variation of the decision process that a product owner is making when choosing an interface or set of capabilities for an application. It is a balance of what the organization wants and needs against the business value delivered. The more technical nature of the work is irrelevant in terms of what the Architects role does for the organization.
There are, at minimum, 7 aspects of architecture that need attention. But applying these across an entire enterprise uniformly is difficult to do organically. Much as I wish it were not true, someone has to make the choices about how a system will be maintained, how do we manage configuration, what systems interact with each other indirectly, and what constraints should be applied to all systems.
For example, all systems will use OAuth2 backed by the Azure platform could be a valid Architectural Choice. Each process in the system will interact via an Event Bus could be another. I could go on with dozens more examples, but the point is, many of these choices would be different on a per application basis when observed in isolation.
So I put forth the notion that an Architect is a specialization of Product Owner. A person with technical skills who understands both the economics of software development, the human aspects of organizational growth and stability, and the technical tradeoffs among the array of technologies available. Beyond that, their skills parallel those of a product owner.
An architect needs to solicit the business for information about what needs to be true. Understand those constraints and find technological solutions to them. All the while, an architect must be conscious of the organizations ability to achieve and maintain those objectives, both financially and practically. For example, if an Architect specified a technology outside the reach of the developers technical acumen without a plan for training and sufficient time for experimentation by the team, he or she would be failing. Similarly, if the revenue stream is too small to sustain a multi-million dollar installation of technology, the architect would likewise be failing. Additionally, an Architect should be looking at the long term impact of technology choices including, operating cost, license and maintenance fees, availability of hirable workforce, availability of training and support, and general applicability to domain problem solving.
This is just a variation of the decision process that a product owner is making when choosing an interface or set of capabilities for an application. It is a balance of what the organization wants and needs against the business value delivered. The more technical nature of the work is irrelevant in terms of what the Architects role does for the organization.
05 March 2017
I'm a PO and so should you!
The role of a Product Owner (PO) is a fascinating one. Product Ownership is a crazy journey mixing business acumen, technical savvy, organizational skills, and patience. Interestingly it is very similar to the role of Architect. Much of the job is a creative process, translating the needs of the business into a plan of execution. This task is not for the faint of heart.
In my career I've played the role of Product Owner several times. It has been simultaneously the most exhilarating and frustrating experience. On the one had you get to be in charge. You have been handed the responsibility of defining something on behalf of the business. It's a way to make your mark on the world. On the other hand you have an almost infinite number of choices to make, plans to define, and assertions to prove while simultaneously enrolling others in your vision.
I propose that everyone should have the experience of Product Ownership for at least several weeks or months. Developers, Managers, and others fail to appreciate the dichotomy of emotions experienced by the PO. Gaining that perspective will change how we work with the PO.
In my career I've played the role of Product Owner several times. It has been simultaneously the most exhilarating and frustrating experience. On the one had you get to be in charge. You have been handed the responsibility of defining something on behalf of the business. It's a way to make your mark on the world. On the other hand you have an almost infinite number of choices to make, plans to define, and assertions to prove while simultaneously enrolling others in your vision.
I propose that everyone should have the experience of Product Ownership for at least several weeks or months. Developers, Managers, and others fail to appreciate the dichotomy of emotions experienced by the PO. Gaining that perspective will change how we work with the PO.
02 March 2017
A Simple and Effective Way to Size Stories
My grandfather used to say 'Easy for you, difficult for me' as I would insist that whatever we were doing should be easy. On a related note, lately I've been watching a lot of videos (tutorials actually) that describe the overall Agile practices. Several times the topic of card sizing comes up. This has also come up in a few team room conversations lately. Having used Fist of Five, Story Points, and Historical Analysis to size cards in the past I became frustrated with those techniques. They seem to slow down the work in the planning process and the team room. In some cases I've seen noisy arguments arise over what size a card should be. So how could we simplify the process so that we can get to work?
If you are going to do it at all, card sizing is too difficult to get right. That is, if we make it a complicated, objective, and refined process, it is hard to do consistently. So I would suggest a simplification of the sizing process. Just have three sizes. Lets call them Small, Medium, and Large.
Here is how we make it work, and make it consistent(ish).
I've used this process a number of times. It works very well in terms of getting like sized cards grouped together and it is also very fast. The process creates a consistency because it is a relative. We are not trying to find a size by using points or beans or whatever. And we are not trying to determine size in terms of time. We are just determining, relative to each other, what size is this card. The best part is, this process usually takes 10 minutes.
Throw away all the things you have heard about points or time in terms of sizing a card. Think about the sizes only in relative terms to each other. When you are done sizing, pick a numeric value for each size. I like 1, 3, 5, but you can use any set of numbers; the only rule being that they are numerically relative to Small, Medium, and Large.
Now, plug that numeric value into your tracking tool and use that to measure progress. You can get a velocity number from this, or a yesterdays weather report, and figure out how much work you can complete in an iteration. Or if Kanban like systems are your thing, you can use these numbers to determine how fast work flows in terms of size.
All of this comes together to make planning easier and less stressful. It also self adjusts to the teams development. If the team creates a template to speed up some work, the cards will naturally fall into a smaller size because when they determine the relative size they will think, 'Hey, we have a template, this is easy.' So there is no more going back to the history and checking ourselves.
If you are going to do it at all, card sizing is too difficult to get right. That is, if we make it a complicated, objective, and refined process, it is hard to do consistently. So I would suggest a simplification of the sizing process. Just have three sizes. Lets call them Small, Medium, and Large.
Here is how we make it work, and make it consistent(ish).
- Put all the cards that need sizes together. This could be on the same Trello board or taped to a wall. Just so long as they are all visible together. If you have tons of cards (more than 20-30) you might need to batch your work so it will all fit. You want to be able to see all the cards at one time without moving (or scrolling).
- Create three columns. Small, Medium, and Large.
- Now, as a group, pick one card and choose a size. Don't worry if its right, just choose a size, and put the card in that column. When I say as a group, I don't mean a facilitated conversation, I mean everyone start moving cards together.
- Pick up another card and compare it to the card you just placed in a column. Then, place it in a column relative to the first card. If the second card is smaller than the first card and the first card is in the small column, you might need to move the first card to the medium column.
- Repeat the process of selecting a card and placing it in a column relative to the others until all cards are placed.
- Review the cards in those columns to ensure you didn't make a mistake.
- You are done.
Remember that every team member gets a say in the cards size. If a card gets moved several times, thats ok. There might be some discussion if the process devolves into two people moving a card back and forth from Small to Medium, but that is just telling us its time to discuss. More often than not, one or the other person relents and you don't even have worry about it.
I've used this process a number of times. It works very well in terms of getting like sized cards grouped together and it is also very fast. The process creates a consistency because it is a relative. We are not trying to find a size by using points or beans or whatever. And we are not trying to determine size in terms of time. We are just determining, relative to each other, what size is this card. The best part is, this process usually takes 10 minutes.
Throw away all the things you have heard about points or time in terms of sizing a card. Think about the sizes only in relative terms to each other. When you are done sizing, pick a numeric value for each size. I like 1, 3, 5, but you can use any set of numbers; the only rule being that they are numerically relative to Small, Medium, and Large.
Now, plug that numeric value into your tracking tool and use that to measure progress. You can get a velocity number from this, or a yesterdays weather report, and figure out how much work you can complete in an iteration. Or if Kanban like systems are your thing, you can use these numbers to determine how fast work flows in terms of size.
All of this comes together to make planning easier and less stressful. It also self adjusts to the teams development. If the team creates a template to speed up some work, the cards will naturally fall into a smaller size because when they determine the relative size they will think, 'Hey, we have a template, this is easy.' So there is no more going back to the history and checking ourselves.
Subscribe to:
Posts (Atom)