Finally, I get to talk about Lean Software…

…even if it’s only for a few seconds.

I occasionally do training seminars on software development technologies. Some are internal to my company, some are external.  Most are on the more technical aspects of Agile software (using the definition of Agile as “any modern software development practices that work”) such as TDD, design patterns,  and refactoring. What I really care about and want to talk about are Lean Software Development and other more overarching values-based approaches to making software, but there doesn’t seem to be the same level of interest. Until today.

This morning, while I was in the elevator at work, I overheard one passenger (total stranger) ask another “so, what does “kanban” stand for anyway?” the other passenger said she didn’t know.

So I pounced!

I managed to cram a pretty good history of how kanban came from the Toyota Production System into a few floors of elevator travel. And I get the sense of satisfaction that comes from making someone’s day a little more strange.

Checklists are Your Friends (surgery, photography, testing, coding, marketing)

The headline of the local Seattle Newspaper yesterday caught my eye. It was about how surgeons at the UW (my Alma Mater) are now using aviation-inspired checklists to make sure they don’t, you know, leave stuff inside of people. This resonated with me, because I had resolved to making checklists for photo gear packing after a near-fiasco last weekend.

I was taking wedding reception photos as a favor for an old friend. For the most part, I hate the entire idea of doing wedding photography. The risk/stress/reward/effort ratios don’t work out right.  This one actually worked out really well, as the couple and wedding party were all great. They also had a “real” photographer working (who had more invested in one lens than I have in my entire setup, alas) which freed me up to take some more experimental pictures, such as HDR still lifes of the venue, controlled motion blur shots of people dancing, and grainy black and white candids (I love tmax 3200 because of the grain, not in spite of it).

I took special care to make sure that all of my camera and flash batteries were charged before the event, but I didn’t spend a lot of time packing the bag before I left. I just threw everything into the camera bag and ran out the door. When I got to the venue and started putting all of the things together, I found I was missing a small but vital piece, the caddy that holds two batteries and slides into my battery grip. Without it, my DSLR wouldn’t work. Panic!

After calling home 15 times, I finally got in touch with my wife, who graciously drove across town with a small piece of plastic so I could actually turn the camera on. Fortunately, I brought a film SLR as a backup, and had just finished my last roll when she pulled up.

If I had made a simple packing checklist, much pain and fear would have been avoided.

And while I’m not a fan of oppressive standards, heavyweight processes, or detailed artifacts in software development (my thinking is that if you’re constrained by your conventions, the best you’ll ever be is conventional) simple “have I forgotten this” checklists are insanely valuable.  Based on what I’ve seen, they’re also underused. 

My first job in software was split between testing and support for a small company making technical graphics software. The testing department was pretty unstructured. We had reasonable automated test coverage (horrible by today’s standards, but OK for the time) but all manual testing was, “Hey Martin, I just fixed this bug, go poke at it!” and “We’re realeasing a beta next week, test everything!” and “We’ve got a release candidate, get the people from sales and marketing to play with it!”

So, for no other benefit than my own confidence, I made a some checklists, just to keep from forgetting to test specific features/permutations.  Eventually the company adopted my checklists and handed them around when we did our “all-hands” pre-release testing.  Just asking people (including me) to be mindful of the feature list when they were doing their exploratory testing helped us find many problems as well as places where we could improve the user experience.

I saw this again a few days ago when I was looking at a web application that made a lot of pretty common security mistakes (no SSL for login, emailing passwords in cleartext, etc.). “These are all essentially solved problems,”  I thought, “Shouldn’t there be a checklist for this sort of thing?” 

Many experienced folks have a sort of mental checklist. Things they know instinctively to look for. Like my old mentor who would always enter “O’Brien” into name fields to catch inappropriatley escaped SQL input. This is one of the reasons why domain knowledge is so valuable. How do we get people to capture and share this domain knowledge? Couldn’t a development group be able to use a set of mature “don’t forget to think about thing X” checklists as a competitive advantage for design/development/testing?

While writing this, I’m reminded of my favorite marketing professor at the UW. After spending a whole quarter discussing different theories, reading case studies, and pulling examples from real-life companies, the last day of class she said (and I’m paraphrasing here, because that was some time ago).

In the real world, when you start in marketing professionally, it’s just checklists: Have I identified the market for my product or service? Have I explained my offering to someone who doesn’t understand it? Have I underpriced? Have I overpriced? Am I saying something stupid or offensive in this ad? How will my competitors react to this change? How will my customers react to this change?  The answers are all easy, but bad marketers forget to ask the questions.

Sure, that doesn’t get you to greatness (or even guarantee goodness), but it at least keeps you from forgetting about the obvious.

Another Decompression Artifact Example: Domain-Specific Languages (DSLs)

This is a particularly odd example, as the three-letter-acronym “DSL” is already in wide use as the name of a technology nobody really understands (Digital Subscriber Line). It reminds me of the time Microsoft rolled out the acronym “DNS” for Digital Nervous System. This isn’t quite that bad, but is still pretty confusing.

Martin Fowler is been writing about Domain Specific Languages for some time now. He’s apparently even writing a book on the subject at the moment. For the longest time, I just ignored blog (and bliki) posts on the subject, as I read the title and immediately assumed that it was something that wouldn’t work for me. It was only when a friend said “no really, you need to read about this” that I actually got it.

In the style of my previous decompression artifacts, I’ve created one for DSLs.

DSL Decompression Artifact

Once you get past the almost inevetable initial misunderstanding of what it actually is, creating a domain-specific, fluent, expressive interface for your domain objects is a really cool idea. It’s also something you can work with incrementally. If you just change every void method ot a “this” method, none of your existing clients will break, and people who aren’t down with DSLs don’t have to do anything any differently.

On a side note: I recently did a TDD presentation for a large-ish company in Portland that has been working with ThoughtWorks for a while. One of the attendees said to me, before I started, “Oh, someone said Martin was doing a presentation and I was expecting Martin Fowler.”

Ouch. Talk about living up to high expectations. I’ve been a big fan of Fowler’s work (and of ThoughtWorks in general) for a while now. There are actual new ideas in his writing, while I just organize, package, and give context to existing ideas. 

While daunted, I think I managed to put on an OK presentation.

The solution here is not process dogma

The other day I was discussing a process/dev workflow problem with one of my friends. I managed to get a basic understanding of what the problem was (team disagreement about the importance and sequence of sprint reviews, retrospectives, and planning) but we were both too pressed for time to brainstorm for a solution. He had a meeting to attend, and I had a demo to give.

The only advice I gave was, “The solution here is not process dogma. You can’t just fall back on the Scrum rulebook and say ‘we’re supposed to do it this way’, you have to get to the value of why you should do the previous review/retrospective before the next planning.”

The value, of course, is that you should be taking what you learned from the last sprint and using it to inform your actions of your next sprint. It’s Scrum’s larger-scale feedback loop (the small feedback loop is the daily meeting).  Inside or outside of Scrum, feedback loops are important for making software well.

When I was thinking about it later, I realized that process dogma is never the solution. Software development is intellectual work, and to make a persuasive case with skeptical people, you have to do better than “because the book says so.”

Code Smells, Correlations, and Poisoned Coffee

Winston Churchill had a much faster and sharper wit than I have. Consider this* famous exchange:

Lady Astor: “If you were my husband, I would put poison in your coffee.”

Churchill: “If I were your husband, I would drink it.”

I, on the other hand, always think of the correct thing to say in an argument a few days later. It’s not just for ex-post-facto arguments, either. I’ve been doing some technical trainings lately, and I try to have a more conversational style than just reading lots of bullet points from slides. I figure that if I don’t understand a topic well enough to speak about it extemporaneously, than I have no business talking about it.

In the last presentation I made, I talked about the practice of refactoring and the concept of code smells.  I gave examples of a few of high-value smells and then gave this little wishy-washy disclaimer.

“When you encounter these code smells, it doesn’t mean that you have to change it, it just means that you should look at your code closely here, as you may have problems.”

It’s not so bad, it’s pretty much what everyone says about refactoring. What I should have said, was this:

Code smells are correlations to quality problems. Heavily commented code blocks aren’t necessarily bad, but lots of comments very strongly correlate to readability problems. You don’t fix it by deleting the comments. You fix it by making your code readable enough to stand without the “how does it work” comments.

Long methods aren’t necessarily bad, but long methods very strongly correlate to cohesion problems. It’s possible, and sometimes required, to have a long method that’s perfectly cohesive, but it’s outside the norm.

And, of course, you don’t fix the problem based on the correlation to the problem, you fix the actual underlying problem. Breaking a long ProcessThings() method into three arbitrary methods called StepOne(), StepTwo(), and StepThree() doesn’t actually make the code any better.

You see, that’s not wishy-washy at all, and it appeals to the distinction between correlation and causation. It’s not as funny as poisoned coffee, but it has some concreteness to it.

*After looking up the Astor/Churchill exchange, I found that it’s very possibly an apocryphal story. Oh well, it’s still funny.

Testing Abstract Classes In Isolation

In my post about guilt as a code smell, a comrade pointed out that it’s perfectly possible to test abstract classes in isolation, you just make a concrete derived class as part of the test (thanks Craig!). Having a distinct concrete subtype for testing is something I’m already doing a lot with endo-testing, so it’s not even totally without precedent.

It does still bother me, though, and I’m not 100% sure why. Some thoughts:

Let’s say your abstract class is using the Template Method pattern, where it has a public method which just delegates “downwards” to abstract methods with different overridden implementations. This is a perfectly good use of an abstract class, yet it seems kind of pointless to test in isolation, as you’re going to be testing each implementation and will be testing those base classes anyway. 

The scenario that I had in the other post had a different kind of abstract class, with no public methods, just protected ones. I’m just achieving zero redundancy by moving code logic upwards in the tree. Testing here becomes trickier, as there’s no publicly exposed design surface. Should I just make one up? The right solution, for me, for that time, was not to test the abstract class, but to move that logic into a distinct service class so I could work with it more directly.  It’s textbook “favor composition over inheritance” design patterns stuff.

In any case, I stand corrected. It’s absolutely possible to test an abstract class in isolation. It is impossible, however to test a base class in isolation without testing its abstract class. Which could make testing the abstract class in isolation kind of pointless.

Narcissism

I was reading the post on Narcissism over at the (always excellent) Coding Horror Blog and I was reminded of something that happened to me.

Many years ago, I was disappointed by my job. I was working at a small consulting company which had been mostly a software development outfit and was transitioning to being more of a general marketing consultancy. I didn’t mind that as much, I have a greater love (or tolerance, depending on your perspective) for marketing than the average developer. Actually, I was driven out by a top-down mandate to “improve our process” which was manifest around trying to adopt development methodologies that were state-of-the-art thirty years ago. It felt as if they were saying to me “all of those things you did to make the last project you ran a big success (tight feedback loops, close developer-to-customer collaboration, design for change, light up-front-documentation)… well, don’t do any of them again.”

So I quit.

In retrospect, I think it would have been possible to improve the situation, but I didn’t yet have a solid handle on why I was doing the things I was doing and how to help a software development team be more effective. I was still essentially “in the closet” –embarrassed that I didn’t want to write 200 page functional and technical spec documents before doing any actual coding. This was before the Agile/Scrum concepts were as mainstream as they are now.

When I was interviewing for another job, I found myself absolutely enthralled by one of the interviewers. He seemed like the single most brilliant developer I had ever met. I was so eager to work with this guy, that I let myself overlook a bunch of warning signs about the organization (legacy code base, previous-generation languages/tools, uninteresting problem domain, deplorable office space, disrespectful management, etc.). I wound up taking the job.

Many months later, as I was trying to figure out how I came to be in the horrible situation I was in, I came to the shameful realization that I thought this guy was brilliant because he reminded me of myself. It was narcissism, plain and simple. Ever since then, I’ve been cautious to think about why I think someone is so amazingly smart.

The same phenomenon came up again last summer, when I did a “Pragmatic TDD” seminar presentation for a handful of development companies. After one presentation, a guy came up to me and said “Your presentation was great. Just brilliant. This is exactly what I’ve been advocating we do for forever.”

Of course I brilliant, I was just like him.

Now, I’m trying to do a better job of being honest with myself, challenging myself, and listening intently to those I immediately disagree with.

My continuing love affair with ReSharper: Indicating Recursive Calls

I generally believe that comments should be about “why is this code doing this” instead of “what is this code doing” because if you feel you need comments to explain what your code is doing, it could probably be refactored to be more readable and/or intention revealing.

One exception that I’ve often made is for recursive calls. I generally write a comment indicating that the method is about to call itself and why. This may be left over from my first CS class at the University where I had some kind of mental block around recursion, I don’t know.

So, I was delighted to see ReSharper give a little visual indication of a recursive call in the margin.

Recursive Picture

This useful when doing recursion on purpose (this example was using reflection to populate test data into properties, I would recurse when a property was a complex type), but it’s even more useful if you do recursion on accident, as in this public property returning itself below.

 Bad Recursion