scrumbut

October 13, 2006 at 12:05 pm

As somebody who is interested in Scrum but hasn’t yet had a chance to try it, I’ve been paying attention to the various experiences people are having with it.


I’ve been noticing something for a while, but I didn’t really realize that there was something bigger going on.


I call that phenomena “Scrumbut”. It shows up in the following way:


We’re doing Scrum but…



  • our sprints are 12 weeks long…

  • we do two normal sprints and one bugfix sprint…

  • we do all our planning up front…

  • we skip the daily meeting…

  • our managers decide what’s in each sprint…

  • we haven’t read the books yet…

  • our team has 30 people…

I’m not a strict methodologist – a specific methodology may need to be adapted to a specific situation. But most of these are anti-scrum rather than modified-scrum.


That this phenomena exists may not be news to you, and it wasn’t to me. But what I realized this last week is that scrumbut has led to another phenomena…


Namely, it has led to scrum being a naughty word. Managers are working with groups that say they are doing scrum, and then when scrumbut doesn’t work, they decide that scrum doesn’t work.


How to approach this? Well, I think you need to advocate specific principles rather than advocating scrum. If you tell your management that you are going to be “ready to release” on a monthly basis and that they get to give feedback on what has been done at what to do next every month, I think you will likely get a better response.

The psychology of arbitrary limits

October 4, 2006 at 7:50 pm

NewsGator – which I use to fetch blog posts – today decided to fetch an August third post for me. At least it’s from this year.


In it, Larry talks about the volume control of a TV going from 0 to 63. And he discusses a possible reason for it, as do many of his readers.


Which brings me to:


Eric’s Law of Arbitrary Limits


If you are designing a piece of tech gear – be it hardware or software – and you need to choose an arbitrary limit or range for something, make sure the limit is either 2^n or 2^n – 1.


The majority of the developers who use your product will convince themselves that you’ve chosen that limit for some well-thought-out reason, such as the internal data structure of your product, rather than just choosing a number because. They will speculate on why you chose that particular number, and you won’t spend your time justifying the limit.


And they will be happy that they understand “the secret” behind why you chose such a strange number…


 

Agile development and the Software Researcher

October 3, 2006 at 10:42 am

A while back I came across this post about agile.


I originally was going to write a comment about that post, but I think the commenters have done a good job at that. I will point out that the environment described in the post is a lot like many of the internet boom startups, few of which are around right now.


But in writing some thoughts down, I realized that I was really writing about why I found agile to be interesting. So that’s what this post is about.


I’ve worked on a ton of projects, some short, some long, some small teams, some big teams. But fundamentally, writing software is an exercise in:



  • Making progress in the face of imperfect information

and



  • Managing change

These shouldn’t be a surprise to anybody. When we start coding, we always have imperfect information. We don’t know if our design will really meet the customer’s needs, we don’t know how long it’s going to take us to write, we don’t know if our architecture is feasible to build, we don’t know if it will perform well enough,  etc. And things will change along the way. Market conditions will change. Customers will modify their priorities. New technology will become available. People will join or leave the team.


There’s a name for trying do something in that sort of environment, and it’s not “engineering”.


It’s research.


Applied research, to be specific.


And doing research requires a different approach than engineering.


Way back in 1961, President Kennedy made his famous “moon speech“.  At that time, the only US astronaut was Alan Shepard, who had flown a 15 minute sub-orbital flight. The ability to send people to the moon seemed out of reach. But the leaders at NASA came up with a plan – they decided on three different programs: Mercury, Gemini, and Apollo. Each program had a theme and a set of goals, and each flight had a set of smaller goals.


Sometimes things worked, sometimes they didn’t. After each flight, they looked at what had happened, decided how to adapt, and went on to the next flight. And over the span of 8 years, they accomplished their goal. All by following the “design a little, build a little, fly a little” approach.


After Apollo, NASA decided to build the shuttle. They did a lot of design up front, made a lot of promises (both schedule and capabilities) and then started building. They ran into lots of difficulties with the main engines (ultimately solved), and the thermal protection system (not really solved). Ultimately, they finished the vehicle, but it took years longer than they expected and ultimately didn’t do what they had designed it to do or what they needed it to do. And it has very high maintenance costs.


The analogy to software development projects should be obvious. Shuttle is like most big software projects – lots of planning up front, lots of promises, followed by delays as problems are addressed, and then the ultimate release of something that doesn’t measure up to the original idea. We convince ourselves that “this time it will be different”, despite the fact that the same thing has happened every time we take this approach.


Incremental development accepts the realities of the environment, and takes a different approach. You know that you don’t know enough to finish the project and you know that things are going to change, so you bite off a manageable portion – say a month’s worth of work – do enough design, write some code, and then see how well it works.


And after that month, you modify your plan based on what you learned.


Design a little
Code a little
Fly a little


That’s what agile means to me.

Yellow Sticky Exercise

September 21, 2006 at 10:25 pm

Yellow Sticky Exercise


Take one pack yellow stickies (aka “Post It” brand sticky paper notes). Place them strategically on your hands and arms, and wave them around for 10 minutes.


Wait… That’s the wrong version.


The yellow sticky exercise is a tool that is used to collect feedback from a group in a manner that encourages everybody to give feedback, doesn’t waste time, and lets people give the feedback (mostly) anonymously.


Microsoft has a tradition of doing “Post Mortems” on our projects, which are designed to figure out what went wrong, what should be done about it, and assign an owner. What typically happen is the group complains for an hour, three people dominate the conversation, several rat holes are encountered, a few things get written down as action items, and nothing ever happens with the results.


The yellow sticky exercise is an alternative. It works well whenever you want to figure out the combined opinion of the group. It was taught to me be a very sharp usability engineer.


Get everybody together in a room. Each person gets a pad of stickies and a pen. Both pens and stickies should be the same color, so things are anonymous.


In the first segment, each person writes down as many issues/problems as they can, one per sticky note. It’s useful to tell people ahead of time so they can come with lists ahead of time, but that’s not necessary. This generally takes about 10 minutes, and you continue until most of the people have run out of things to write down.


Ground rules for issues:



  1. They can’t be personal (ie no names on them)

  2. They should be specific

  3. They should have enough detail so that anybody in the room could figure out what they meant.

If you’re doing this to collect the problems you have, it’s good to ask people not to put down anything personal, and to include enough data so that


At this point you have a lot of diverse feedback items, and you need to get them placed in groups. That is done by the group. You ask the group to put the stickies up on your wall/whiteboard in meaningful groups, and just let them go at it. When there’s a group of 5 or more stickies, ask somebody in the group to come up with a label for the group and write it on the whiteboard or on a sticky. You should also ask people to move stickies around if they belong in a different group.


When everything is on the wall and people are happy with the groups, you’re done with the group. Somebody will need to stick the stickies on paper and own typing them all up.


If you do this, I’m confident that the breadth and the depth of the feedback will be much better than other methods.

Bugs, blogs, and surrogates

September 21, 2006 at 9:39 pm

Back in 1996, I was a QA lead for the C++ compiler, and our group wanted to incent people to fix and close bugs.


One of the other QA leads had the brilliant insight that lego blocks make excellent currency amongst development teams, and I – because of my demonstrated aptitude in generating reports from our bug-tracking system – became the “Lego Sheriff” for the group, handing out blocks. I believe the going rate was three blocks per bug.


Not surprisingly, some people started to game the system, to increase the number of blocks. Those of you who are surprised that somebody would go to extra effort to get blocks that retail at about a penny per block have never seen a millionaire fight for to get a free $10 T Shirt.


But I digress.


That there was a system to game was due to a very simple fact. Our goal wasn’t really to get people to fix and close bugs, our goal was to get the product closer to shipping. But we didn’t have a good way to measure the individual contribution to that, so we choose active and resolved bug counts as a surrogate measure – a measure that (we hoped) was well correlated with the actual measure.


This was a pretty harmless example, but I’ve seen lots of them in my time at Microsoft.


The first one I encountered was “bugs per tester per week”. A lead in charge of testing part of the UI of visual studio ranked his reports on the number of bugs they entered per week, and if you didn’t have at least <n> (where <n> was something like 3 or 5), you were told that you had to do better.


You’ve probably figured out what happened. Nobody ever dropped below the level of <x> bugs per week, and the lead was happy that his team was working well.


The reality of the situation was that the testers were spending time looking for trivial bugs to keep their counts high, rather than digging for the harder-to-find but more important bugs that were in there. They were also keeping a few bugs “in the queue” by writing them down but not entering them, so they could make sure they hit their limit.


Both of those behaviors had a negative impact, but the lead liked the system, so it stayed.


Another time I hit this was when we were starting the community effort in devdiv. We were tracked for a couple of months for things like “newsgroup post age”, “number of unanswered posts”, or “number of posts replied to by person <x>”.


Those are horrible measures. Some newsgroups have tons of off-topic messages that you wouldn’t want to answer. Some have great MVPs working them that answer so fast you can’t a lot to say. Some have low traffic so there really aren’t that many issues to address.


Luckily, sharper heads prevailed, and we stopped collecting that data. The sad part is that this is one situation where you *can* measure the real measure directly – if you have a customer interaction, you can *ask* the customer at the end of the interaction how it went. You don’t *need* a surrogate.


I’ve also seen this applied to blogging. Things like number of hits, number of comments, things like that. Just today somebody on our internal bloggers alias was asking for ways to measure “the goodness” of blogs.


But there aren’t any. Good blogs are good blogs because people like to read them – they find utility in them.


After this most recent incident of this phenomena presented itself, I was musing over why this is such a common problem at Microsoft. And I rememberd SMART.


SMART is the acronym that you use to remember the measures that tell you that you’ve come up with a good measure. M means measurable (at least for the purposes of this post. I might be wrong, and in fact I’ve forgotten what all the other letters mean, though I think T might mean Timely. Or perhaps Terrible…).


So, if you’re going to have a “SMART goal”, it needs to be *measurable*, regardless of whether what you’re trying to do is measurable.


So, what happens is you pick a surrogate, and that’s what you measure. And, in a lot of cases, you forget that it’s a surrogate and people start managing to the surrogate, and you get the result that you deserve rather than the one you want.


If you can measure something for real, that’s great. If you have to use a surrogate, try to be very up-front about it, track how well it’s working, don’t compare people with it, and please, please, please, don’t base their review on it.

Feel the pain…

August 21, 2006 at 6:36 pm

Dare wrote a post talking about the advisability of making developers do operations.


Which is really part of a philosophical question…


When you’re setting up a software organization, how much specialization should you have, and where you should you draw the lines around the responsibilities of the various groups?


Some orgs take a very generalized view of what people own, and others take a very specialized view. I’ve worked in both sorts of environments.


I’ve worked for a startup where, as a developer, I wrote the code, tested the code, built the code, made tapes to ship out to customers, and answered customer support calls.


And I’ve worked in other organizations where the job of developer was to implement what was written down in the spec and pass it off to the QA org. Those orgs typically had structures and policies designed to insulate the developers, so they wouldn’t be distracted.


That eliminated a bunch of the outside noise that they would otherwise have to deal with, and make them more efficient at getting their development work done.


And how did those efficient organizations fare in their products?


Not very well.


They were reasonably good at shipping software, but their software didn’t turn out to be very good for users. New updates didn’t address issues that users had been hitting. New features were hard to use and/or didn’t hit the sweet spot. They answered questions that users didn’t ask.


All of this was because the developers were out of touch with people who had to deal with their software. They didn’t feel the pain that the users were experiencing setting up their software. They didn’t feel the pain when a bug in the software meant that the user’s business was loosing money. And they didn’t understand why users were having trouble using features that seemed obvious to them.


All that happened in DevDiv, and the issues showed up in our customer satisfaction numbers. So, it was decided to let developers (and the testers, and PMs…) talk directly with customers.


There was a fair amount of angst around this decision. It would take up too much dev time. Developers would insult customers. Customers didn’t know enough to give good feedback.


But it turned out that all of those things were wrong. The developers liked to solve problems, and they also liked to help people. They remotely debugged customer issues on other continents. And they listened very closely to the detailed feedback customers gave about how the current software didn’t meet business needs and what was good and bad about future plans.


And the organization adapted what they were planning, so that it addressed the areas that needed addressing.


Distraction is not the enemy. Pain is not the enemy. Pain is to be embraced, because only through feeling pain are you motivated to make it go away.

Other views on programming sins…

August 8, 2006 at 1:31 pm

At the beginning of the sin-tacular, I asked for people to come up with their own lists. And here they are:



My original plan was to comment on some of the individual sins that people listed, but they’re all great – you should go and read them all.


I was a bit intrigued, however, by Chris’ comment (or should that be “Chris’ Comments’ comment?):


Hey, Eric, what are the 7 Heavenly Virtues of Programmers?


Hmm…

Seven deadly sins of programming – Sin #1

August 3, 2006 at 5:24 pm

So, the time has come for the worst sin.


Just to recap – and so there is one post that lists them all – here are the ones that I’ve covered so far:



Some people have remarked that all of these are judgement calls, and really more a matter of aesthetics than actual sins.


That is true. I didn’t include things like “naming your variables i, j, & k” as sins, because I don’t think that’s a real problem in most of the code I’m likely to have to deal with, and there really isn’t much argument over whether it’s a good idea or not.


It perhaps would have been better to title this series, “Seven things Eric would really prefer that you don’t do in code that he has to work with”, but that is both ungainly and lacking the vitality of a post with the term “sin” in it.


It’s all marketing, you see – or you would if you were actually reading this post, but given my track record on the last six, it’s probably a good idea to cut your losses now and spend your time more productively, like in switching your entire codebase from tabs to spaces (or spaces to tabs…)


When I was a kid, I was fairly interested in WWII. I read a lot of books about it, from general histories about the war, to books on the warfare in the Pacific, to books about the ground war in Europe.


One of the interesting features of the military during that time – one that I didn’t appreciate until much later – was how they balanced the desire for advancement in their officer corps vs the need to only advance the most talented and capable. There were really two schools of thought at the time.


The first school advocated an approach where a lower-ranked officer – say, a colonel – would be promoted to fill a vacancy directly, on the theory that it made the chain of command cleaner, and you’d quickly find out if he had “the right stuff”.


The second group advocated using “field promotions”, in which a colonel would be temporarily promoted to see if he could perform in the job. The theory here was that the service would end up with only the best colonels promoted, and that it was much easier (and better for both the officer and the service) to let a field promotion expire rather than demote an officer already given a full promotion.


Over time, the approach advocated by the second group was borne out as having far better results, and the danger of the first approach was recognized.


Which brings us on our roundabout journey to our final sin:


Sin #1 – Premature Generalization


Last week I was debugging some code in a layout manager that we use. It originally came from another group, and is the kind of module that nobody wants to a) own or b) modify.


As I was looking through it, I was musing on why that was the case. Not to minimize the difficulty in creating a good layout manager (something I did a bit of in a previous life), but what this module does really isn’t that complex, and it has some behavior that we would really like to change.


The problem is that there are at least three distinct layers in the layout manager. I write a line of code that says:


toolbarTable.SetColMargin(0, 10);


and when I step into it, I don’t step into the appropriate TableFrame. I step into a wrapper class, which forwards the call onto another class, which forward onto another class, which finally does something.


Unfortunately, the relation between the something that gets done and the TableFrame class isn’t readily apparent, because of the multiple layers of indirection.


Layers of indirection that, as far as I can tell (and remember that nobody wants to become the owner of this code by showing an any interest in it or, god forbid, actually making a modification to it…), aren’t used by the way we use the layout manager. They’re just mucking things up…


Why is this the #1 sin?


Well, as I’ve been going through the sins, I’ve been musing on how I ranked them. One of the primary factors that I used is the permanence of the sin.


And this one is pretty permanent. Once something is generalized, it’s pretty rare that it ever gets de-generalized, and I this case, I think it would be very difficult to do so.


<Agile aside>


This might be slightly different if there were full method-level tests for the component – one could consider pulling out that layer. But even with that, it would be hard to approach in a stepwise fashion – it could easily turn into one of those 3-hour refactorings that makes you grateful that your source code control system has a “revert” feature.


</Agile aside>


Or, to put it another, fairly obvious way:


Abstraction isn’t free


In one sense this seems obvious – when you develop a component that is used by multiple clients, you have to spend a little extra effort on design and implementation, but then you sit back and reap the benefits.


Or do you?


It turns out that you only reap the benefits if your clients are okay with the generalized solution.


And there’s a real tendency to say, “well, we already have the ListManager component, we can just extend it to deal with this situation”.


I’ve know teams where this snowballed – they ended up with a “swiss army knife” component that was used in a lot of different scenarios. And like many components that do a lot, it was big, complex, and had a lot of hard-to-understand behavior. But developing it was an interesting technical challenge for the developers involved (read that as “fun and good for their careers”…)


The problem came when the team found that one operation took about 4 times as long as it should. But because of the generalized nature of the component doing the operation, there was no easy way to optimize it.


If the operation had been developed from scratch without using the “uber-component”, there would have been several easy optimization approaches to take. But none of those would work on the generalized component, because you couldn’t just implement an optimization in one scenario – it would have to work for all scenarios. You couldn’t afford the dev cost to make it work everywhere, and in this case, even if you could, it would cause performance to regress in other scenarios.


(At this point, I’m going to have to have anybody thinking “make it an option” escorted out of this post by one our friendly ushers. How do you think it got so complex in the first place?)


At that point, you often have to think about abandoning the code and redeveloping in the next version. And in the next cycle, this group *did* learn from their mistakes – instead of the uber-component, they built a small and simple library that different scenarios could use effectively. And it turned out that, overall, they wrote less code than before.


HaHA. I make joke.


What they really did was build *another* uber-component that looked really promising early (they always do), but ultimately was more complex than the last version and traded a new set of problems for the old ones. But, building it was a technical challenge for the developers involved, and that’s what’s really important…


How do you avoid this sin?


Well, YAGNI is one obvious treatment, but I think a real treatment involves taking a larger view of the lifecycle costs of abstraction and componentization.


It that one general component really going to be better than two custom solutions?


(if you didn’t understand the story, look here and and see what rank is above a colonel…)

Seven deadly sins of programming – Sin #2

July 24, 2006 at 5:33 pm

One of the guys on my wing during my freshman year of college was a trust-fund kid. His great-grandfather had done well in the market, and had left some money for each the great-grandkids.


Michael wasn’t paying for his schooling, nor was he paying for his cars, his clothes, his nice stereo, or his ski vacations. But that was okay with us, because he *was* paying for pizza, and he *was* paying for beer. Or his trust fund was.


Everything was fine until spring came around, and Michael got some bad news. His trust fund had been set up to carry him through 4 years of school, but because he spent money so fast, he had burned through all of it in less than two years. He was forced to get a job at the local grocery store to finish the year out, but couldn’t afford tuition and had to leave school and find a job to support himself.


========


It typically shows up in chapter two or three of the programming book. There’s a section titled something like, “What is an object?”, which speaks in flowing terms about the wonderful work of object-oriented development, and uses one of the following examples:



  • Geometric shapes

  • Animals

  • Musical instruments

  • Cephalopods (rare)

In this section, we find out that a square is an example of a polygon, a cheetah is a cat and also a mammal, and so on.


All of this to introduce is to the concept of “is-a”.


We then see an example where we can ask any polygon how much area it covers, tell any mammal to walk, and tell any cat to ignore us while we’re talking to it, all through the wonders of inheritance and virtual methods.


Good taste and a firm grasp of the relative usefullness of this concept would dictate spending 10 or 20 pages explaining these concepts, but most texts significantly exceed that, and most programming assignments spend a fair bit of time on that as well. Kindof like how linked lists rule your life for a month or so.


It’s therefore not surprising that many younger developers think that inheritance is a feature that you should, like, “use” when you write software.


There are a few problems with this.


The first is that “is-a” is, in my experience, a pretty rare relationship between objects. More common is the “looks the same on one dimension but has different behavior across another dimension”.


Good luck implementing this:


public class Monotreme: Mammal
{
    public override GiveBirth()
    {
        // add appropriate implementation here
    }
}


That’s the sort of thing that tends to be non-obvious when you first create an object, but annoying obvious when you’ve bought into the whole inheritance mindset.


That’s not to say that inheritance isn’t useful. It’s just to say that you should understand that a MemoryStream isn’t really a Stream, at least in the true “is-a” sense, and be prepared to deal with it.


The second problem is more philosophical and aesthetic. I recently wrote code like this:


class ClimbList: List<Climb>
{

}


Which seems like a perfectly reasonable thing to do, at least on the surface.


But the surface – or at least the surface area – is a problem. List<T> is a pretty extensive class, and when I defined ClimbList, I was saying that ClimbList does the proper thing when any of the List<T> methods or properties are called.


I’m pretty sure that’s not true. Or at least, I’m not at all sure that it *is* true (I have no tests to support such a belief), but users of ClimbList don’t have any way of knowing that the only methods I’m currently using are Add() and the indexer. Intellisense brings up all of them when I go to call one of the methods I wrote.


Which brings us in a long and roundabout way to our penultimate sin:

Sin #2 – Overuse of Inheritance

So, what should you use if you don’t use inheritance (and I am advocating that you approach it carefully and thoughtfully – it’s a similar decision to adding a virtual method)?


Composition. Make the object a field inside of your object, and then write the forwarders that you need (it’s usually not more than one or two).


And, if you really need inheritance in your design, add it carefully and thoughtfully.

Seven Deadly Sins of Programming – #3

July 18, 2006 at 5:19 pm

I’m sure this is going to be a contentious one. I don’t have a good story about this one, so I’m just going to go right to the sin.


Sin #3 – Overuse of Virtual


There are two schools of thought when it comes to virtual. They are:



  1. Always use virtual

  2. Only use virtual when absolutely necessary

The first group’s argument is that original designer of a class is a poor judge of how the class might ultimately be used. Making all methods virtual allows the users of the class to easily extend/modify the behavior. Non-virtual methods make more work for the user.


(or that’s the argument I’ve heard – please comment if there’s something I missed…)


The argument is true. Virtual does make extensibility easier. The problem with virtual is robustness.


The original designer of a class has a good idea for what the class is about, and the implementation is designed (either explicitly through the tests written with TDD, or more implicitly through the mind of the designer) to support that idea (or contract, if you prefer).


In other words, the designer has an explicit idea about what extension points he wants to support in the class. If virtual is only on those points, then the designer has (or should have) done sufficient testing on those points, and it’s pretty likely that users who extend through those points get the behavior they want. And since only a few methods are virtual, the fact that a specific method is virtual is an important clue to the user that that method *is* an expected extension point.


If virtual is on every method, the user can extend in a lot of ways, but it’s very unlikely that the designer thought of all those ways – or all combinations of those ways – which means that such a user extension is going into uncharted territory. Maybe it doesn’t work when you try it. Maybe it works now, but breaks with the first update when the object behavior changes.


I prefer the “you can only do these 2 things, but I promise that they work” classes to the “you can do any of these 12 things, but they may or may not work” classes.