Metricism

July 12, 2010 at 9:21 am

Your neologism for the day…

Metricism

A devotion to creating and implementing metrics for a system or process while loosing sight of the real goal.

Examples:

  • Evaluating software developers on how many bugs they fix.
  • Evaluating newsgroup interaction quality based on the percentage of posts answered in the first day.

Thoughts on “Thoughts on TDD”…

April 19, 2010 at 10:46 am

Brian Harry wrote a post entitled “Thoughts on TDD” that I thought I was going to let lie, but I find that I need to write a response.

I find myself in agreement with Brian on many points in the post, but I disagree with his conclusion.

Not surprisingly, I agree with the things that he likes about TDD. Focusing on the usage rather than the implementation is really important, and this is important whether you use TDD or not. And YAGNI was a big theme in my “Seven Deadly Sins of Programming” series.

Now, on to what he doesn’t like.

He says that he finds it inefficient to have tests that he has to change every time he refactors.

Here is where we part company.

If you are having to do a lot of test rewriting (say, more than a couple of minutes work to get back to green) *often* when you are refactoring your code, I submit that either you are testing things that you don’t need to test (internal details rather than external implementation), your code perhaps isn’t as decoupled as it could be, or maybe you need a visit to refactorers anonymous.

I also like to refactor like crazy, but as we all know, the huge downside of refactoring is that we often break things. Important things. Subtle things. Which makes refactoring risky.

*Unless* we have a set of tests that have great coverage. And TDD (or “Example-based Design”, which I prefer as a term) gives those to us. Now, I don’t know what sort of coverage Brian gets with the unit tests that he writes, but I do know that for the majority of the developers I’ve worked with – and I count myself in that bucket – the coverage of unit tests written afterwards is considerably inferior to the coverage of unit tests that come from TDD.

For me, it all comes down to the answer to the following question:

How do you ensure that your code works now and will continue to work in the future?

I’m willing to put up with a little efficiency on the front side to get that benefit later. It’s not the writing of the code that’s the expensive part, it’s everything else that comes after.

I don’t think that stepping through test cases in the debugger gets you what you want. You can verify what the current behavior is, sure, and do it fairly cheaply, but you don’t help the guy in the future who doesn’t know what conditions were important if he has to change your code.

His second part that he doesn’t like backing into an architecture (go read to see what he means).

I’ve certainly had to work with code that was like this before, and it’s a nightmare – the code that nobody wants to touch. But that’s not at all the kind of code that you get with TDD, because – if you’re doing it right – you’re doing the “write a failing tests, make it pass, refactor” approach. Now, you may miss some useful refactorings and generalizations for this, but if you do, you can refactor later because you have the tests that make it safe to do so, and your code tends to be easy to refactor because the same things that make code easy to write unit tests for make it easy to refactor.

I also think Brian is missing an important point.

We aren’t all as smart as he is.

I’m reminded a bit of the lesson of Intentional Programming, Charles Simonyi’s paradigm for making programming easier. I played around with Intentional Programming when it was young, and came to the conclusion that it was a pretty good thing if you were as smart as Simonyi is, but it was pretty much a disaster if you were an average developer.

In this case, TDD gives you a way to work your way into a good, flexible, and functional architecture when you don’t have somebody of Brian’s talents to help you out. And that’s a good thing.

The power of “ouch”…

March 25, 2010 at 12:06 pm

From my bicycle blog…


Three of them

The power of “no”…

December 1, 2009 at 10:25 am

Eric Brechner wrote an interesting post titled “Don’t panic“, about how to deal with requests. I sometimes agree and sometimes disagree with what Eric writes, but it’s usually a pretty good read.


In this case, I agree with his approach, but disagree with his advice.


He advocates that when anybody comes with you for a request, your first response should always be “Yes, I’d be happy to help”.  Which is wrong.


Way back when my daughter was 4, I was sitting on the couch and she came and asked me for something. My memory is a bit hazy on what she asked for, but I think it was some sort of snack. I didn’t think deeply about it, and made a quick decision and answered “no”. She got pretty upset and started crying and asked again.


At that point I had a quandry. I thought about it a bit more, and realized that her request was a reasonable one (lunch was a long time ago) and that there was really no reason to grant it, but I knew that I couldn’t because at that point is wasn’t about the request but instead was about the way it was asked and the pattern me changing my mind would set. I didn’t want to set up a behavior where getting upset and crying is expected to make your dad change his mind. So I held firm.


And felt really bad about it, because I made the wrong initial call.


The whole point of the story – assuming that there is a point – is that you need to look not at the current interaction but instead at the meta-level. What message is your response sending? What pattern of interaction is it reinforcing?


If somebody comes and asks you to do something and you say, “yes”, once that word leaves your lips you can assume that the person making the request will think that they are getting everything they want from you. They have in mind a big feature delivered on an impossible date, and your job then becomes trying to scope their expectations down to something manageable, but even if you succeed they’ll still be stuck on what they originally had in mind, and will be disappointed with you.


Not to mention the fact that if you immediately say “yes”, it seems like you’re either working on unimportant stuff and/or not working hard enough.


The right thing to do is to say “no”, but in the right way. Something like “I’m/we’re currently booked and have a lot of high-priority work planned, so I think that would be hard to fit in, but let me understand exactly what you’re asking”. That puts the requester in the position of having to convince you of the importance of what they want to do and be able to explain the details coherently.


At that point, you can start the nuanced discussions that Eric talks about – talking about the details of what they want, why they think it’s important, etc. It becomes very clear very fast whether the requester has done his homework, and if they haven’t you can point out the additional things he needs to figure out before you talk more. If he has done her homework, you can discuss where you think the feature ranks (always subject to the approval of whoever approves features), and how it might be broken apart/modified to bring it in earlier.


At that point, the answer usually becomes, “yes, we can do <x> in timeframe <y>”, which makes the requester happy – you’ve spent the time to explain to them why you put a specific priority on the request and you’ve made your life harder by rearranging things to slot their request into your current schedule and (probably) taking on the task of explaining to everybody who’s below the new feature’s priority why they aren’t getting what they expected.


And, you’ve set up a healthy pattern of behavior. Requesters are likely to do a bit of homework before they talk to you, and you are busy but willing to take on new work if it makes sense to do so.


And that’s the power of “no”.

Thoughts on agile design and platforms

August 14, 2009 at 2:47 pm

I started by writing a broad post about design, and it got away from me (apparently I should have spent some time designing the post first…), so I deleted it all and decided to write something shorter, and, with any luck, more understandable and useful.

I’ve been reading some discussions about how design relates to Agile. Some teams get into trouble because they think that agile means “no design”, when in fact it means “right design”.

The whole point of design in my mind is to save you work later on. There’s a sweet spot between no design and big design that makes sense in a particular situation. I don’t think that’s a unique insight at all, though I have seen groups how use the “design document” approach where there’s a document with 18 sections in it that everybody has to use.

The two areas I would like to talk about are about what you are building and the scope of what you are doing right now. I’ll talk about scope first.

The amount of design you should do depends on the scope of what you are doing, and scope in this situation doesn’t mean “amount of code change” (though it often correlates somewhat with that), it means “impact of code change on the customer”. This is obviously different for every change you make to the code, and my general guideline is that spending 5 minutes bouncing your thoughts off of somebody else generally gives you a good enough conclusion about how much design is required. Notice that I said “guideline” – I expect that developers can use their best judgement about when they can make changes without consulting with others.

Some people would say that not having the opportunity to make a wrong choice about when to consult with others is a strength of pair programming. I think that’s probably true, but obviously only works for teams that do pair, and that’s not that common in my neck of the woods (and, I suspect in others).

So, anyway, that’s what I think about scope, and, once again, I don’t think it’s a unique insight.

My second point – that the amount of design depends on what you are building – is something I haven’t heard talked about much, especially in agile circles. Because most software developers deliver applications, the agile processes are described in that context.

And in that context, I think that many developers do far too much design up front. You can spend 3 days writing something up that covers how you will do something, or you can spend 2 days doing early implementations and then know which one works better, and have real code to show people. Trying to figure out how things should work before you write them is often less efficient than just writing them when you need them.

Given that I consider premature generalization to be the #1 sin of developers, no surprises there.

But – and I think I may be finally getting to the point – that perspective comes from applications, where you own the code that you’re building, and refactorings can be done when you learn more.

Platforms are different.

If you are building a platform, things get a bit schizophrenic. Internally, you are an application – you can refactor the internals without a lot of impact elsewhere, and therefore the amount of design you do should keep that in mind.

But externally, people depend on your APIs to stay the same. This means that, for a given feature, you need to get it right (or as close to right as you can) on your first release. It also means that you need to think about how the feature that you’re doing right now might be extended for things you might do in the future.

Which is exactly the thing that you shouldn’t be doing if you’re building an app, because it’s a pain, it’s expensive, you’ll make the wrong choices, and you’ll have to throw work away.

In my current team, we own both applications and platform API, so we get to spend time in both of these areas.

And now it’s lunchtime. I may write a future post on how I think you should do platform design.

Is programming a generic skill?

June 25, 2009 at 12:50 pm

Came across a post by Justin Etheredge discussion whether changing between languages is just a matter of syntax.


Or, to pick a specific example, can a Java programmer quickly and easily learn to write C# code?


The answer is obviously “yes”. Development is about a way of thinking and approaching problems, and given the similarity between Java and C#, a good Java developer should take a minimal amount of time to learn how to write functional code in C#. The biggest barrier is libraries, which are more different than the languages are.


The answer is equally as obviously “no”. Sure, you can write functional code, but you will not be able to write idiomatic code. Like a high school senior with 4 years of French class on a trip to Paris, you can make yourself understood, but you aren’t going to be mistaken as a native. You ask a question, somebody replies, “Ce ne sont pas vos oignons”, and you just end thinking of soup.


So, yeah, you can write C# code, but it’s going to be Java written in C#. Given the closeness of the languages, it may be sufficient, but you’re going to force some refactoring on any idiomatic C# speakers who inherit your code.


It can be worse – when I first started writing in Perl, I wrote C code in Perl, which just doesn’t work very well. And over time, I became at least functional, though perhaps not idiomatic in Perl (though, because of TMTOWTDI, it’s hard to judge that in Perl).


However, if you can become idiomatic in multiple languages, your toolset broadens, and you become more useful in all your langauges.

Triathlon report

September 26, 2008 at 6:15 pm

For your “enjoyment”, a report on the Triathlon I did last Sunday…

Taking on dependencies

July 8, 2008 at 12:11 pm

A recent discussion on how to deal with dependencies when you’re an agile team got me thinking…


Whether you are doing agile or waterfall (and whether the team you are dependent on is doing agile or waterfall), you should assume that what the other group delivers will be late, broken, and lacking important functionality.


Does that sound too pessimistic? Perhaps, but my experience is that the vast majority of teams assume the exact opposite perspective – that the other group will be on time, everything will be there, and everything will do what you need it to do. And then they have to modify their plan based upon the “new information” that they got (it’s late/somethings been cut/whatever).


I think groups that plan that way are deluding themselves about the realities of software development. Planning for things to go bad up front not only makes things smoother, you tend to be happily surprised as things are often better than you feared.


A few recommendations:


First, if at all possible, don’t take a dependency on anything until it’s in a form that you can evaluate for utility and quality. Taking an incremental approach can be helpful here – if you are coming up with your 18-month development schedule, your management will wonder why you don’t list anything about using the work that group <x> is doing. If, on the other hand, you are doing your scheduling on a monthly (or other periodic) basis, it’s reasonable to put off the work integrating the other groups work until it’s ready to integrate (based on an agreement of “done” you have with the other group).


That helps the lateness problem, but may put you in a worse position on the quality/utility perspective. Ideally, the other team is already writing code that will use the component exactly the way you want to use it.  If they aren’t, you may need to devote some resources towards specifying what it does, writing tests that the team can use, and monitoring the component’s process in intermediate drops. In other words, you are “scouting” the component to determine when you can adopt it.


 

Individual Empowerment and agile…

April 28, 2008 at 12:31 pm

(Interestingly, I find myself writing more about agile and team stuff now that I’m not on a development team….)


 


This is in response to a question about how you balance individual empowerment with the collaborative approach on a agile tem… 


 


*** 


 


Agile is all about the team, and being on an agile team requires participants to give up some autonomy towards the team. The team is empowered to do what they need to do to reach their goal. If there are issues around how things should be done or what decision is right, the team needs to come to a decision, and I would encourage management to let the team try to do it.  Further, the team needs to “meta rules” around how to make decisions, and they also need to develop those.


 


This is very different than the “alpha geek” culture that exists in some groups, where a small number of developers are interested in wielding power. There are some individuals who just aren’t willing/able to work collaboratively – I’ve worked with a few, and if you are trying to run an agile team, they are likely better in a different position.


 


One of the teams I was on basically came to this agreement:


 


Developers are expected to use their best judgement when deciding what advice to seek when they are doing development.   There are no rules around when you should seek advice, but as a rough guideline, extending functionality under existing patterns is something you can safely do on your own, and big refactorings or new components are areas when you should definitely seek advice. In between, think about the implications of any design choices you might make, and act accordingly.


 


The other approach is to adopt pair programming, which is a bigger cultural change, but generally if you get two people thinking about decisions they usually make the right decision about involving others.

Project managers for agile teams…

March 20, 2008 at 4:48 pm

A recent question about skill requirements for project managers of agile teams led me to write this:


In traditional project management, “project manager” means “person who is in charge”. In other words, that person makes the decisions, with varying degrees of depth (sometimes it’s high-level, sometimes it’s micro-management).


 


Agile doesn’t have somebody in change – inherent in the concept of agile is that the group is responsible and the group decides.


 


There *is* somebody who facilates (scrummaster in scrum, coach in XP), but their job is very explicitly not to make decisions. That means that the person who takes that role needs to be mindful of that and willing to push any decisions that rise up back down to the time. If the person has previous experience (and a preference) for “being in charge”, they are unlikely to do a good job in that role. If they aren’t thoughful about group dynamics in general, they may not do a good job in that role.


 


Double that comment if the group is not experienced with making decisions together. If they tend to defer upwards and the facilitator is used to making decisions, you probably won’t get a good result.