November 2008 Entries

For some reason, I've been obsessed with Behavio(u)r Driven Development for the last few months. I've only been doing TDD for a little over a year, and I am totally loving what it's done for my design, so why would I look for something else? It's NOT something else. Dave Astels says, "Behavior Driven Development is what you are doing already if you are doing Test Driven Development very well." BDD is how we're supposed to be doing Test Driven Development.skull_brain_xray

The problems that people end up having with TDD stem from the origins of TDD. People (testers mostly) used to write tests to test units of code that the programmers had written to ensure that the code worked. When people started talking about Test DRIVEN development, most people cheerfully thought, "Oh, I just need to write my unit tests BEFORE I write my code." That's NOT TDD. At least it's not the essence of TDD. Just writing unit tests first doesn't get you the full benefit of using those tests to drive your design. It's not that TDD can't give you that benefit. It's just that since TDD comes from a birthplace of testing and a language centered around testing, that developers using tests to drive their development think about testing. They think in the terms they are using. They think in terms on Tests and Fixtures and Assertions, and they lose site of driving the design with the tests.

Somewhere in TDD-land in 2006, Dan North wrote an article about his frustrations with coaching programmers in TDD. He noted that developers seemed confused about using tests to drive their design. He started the BDD "movement" out of that frustration. He wanted to help programmers understand how TDD works and he knew that the language of testing was the largest barrier. The language of "tests" and "assertions" was distracting developers from the main benefit of TDD, which is to drive you design and observing behaviors within their system.

I, too, was frustrated with my inability to grok TDD and to understand when I was testing too much or too little or when I was testing the wrong thing or if I was really testing what I thought I was testing. All my pain came from testing "units". What's a unit? A class? A method? An assembly? We took that language of testers and shoe-horned it into our development methodology. The thing is, TDD is NOT ABOUT TESTING. Guffaw, you say? Why do they call it TEST Driven Development then? Because the pioneers of TDD used testing tools to set up observable specifications, that would help them understand what their system should do from a business standpoint.

Over the coming weeks and months, I'll be chronicling my submersion into BDD. I've been reading white papers, trying different tactics/languages, watching videos and reading lots of BDD framework code. I've had some significant "A-HAs" with respect to BDD and I want to chare them on my blog for three main reasons: One, I want people who are the masters of BDD to tell me when I'm on the right track, off the reservation and when I'm full of it. Two, I want others to learn from me and teach me too. I am hoping to get a small project started and get it out on Google-Code and let people get involved and DO some BDD. Finally, because I am absolutely obsessed with it. I have no idea why I am drawn to it, but I absolutely can't get enough.

Look for the first part of this series very shortly (like this weekend), and PLEASE comment on what I am doing. It is sometimes very hard to recover from going too far in the wrong direction when you are learning something new. So if you're a BDD newbie, tune in and get involved and if you're an old hat, help a brother out.

~Lee

QUICK THOUGHT: The engineering practices in Extreme Programming (Like TDD, Pair Programming, etc) can lead you to improving your code. But it won't do it for you. TDD will point out design flaws, but it won't GIVE you good design skills. If you write lousy code, you'll find it very hard to maintain practicing XP, but XP won't MAKE your code better. You still have to do it. You STILL have to read books, write code and share with other developers.

KAIZEN!

~Lee

Life is sometimes sweeter than we realize. Sometimes we just forget to see it. We complain about work, bills, co-workers and spouses and sometimes forget to look at how awesome our lives really are.

I LOVE be a programmer. I've done a lot of different jobs and I didn't come to programming until my mid-to-late twenties, so I've experienced some really crappy jobs that paid even crappier. At my current job, I was given the freedom to choose how I would develop this new project, what language, what tools and what people. I've failed as much as I've succeeded so far (but I fail fast), and my boss hasn't blamed me once for my failures. It's been awesome and overwhelming.

I also Love my wife. I dated a lot of different girls, some were great and I screwed it up, and some were just screwed up. I feel like now all those failures were simply meant to lead me to my current wife. We've been married 11 years in January and we've been together for 15 years. I couldn't imagine caring about anyone as much as I care for her.

I have a nice house in a nice neighborhood. I don't have a NICE house in a NICE neighborhood, but I am not struggling to work out where the money for the mortgage is coming from every month either, and there is plenty of money left over for dining out, movies, etc.

I am also planning the first (that I know of) Kansas City Day of .Net. We are almost full on registrations (only 2 seats left), and an absolutely outstanding line-up of speakers and topics. The vendors are clamoring to help sponsor the event, and we've got an XBox 360 Pro for a grand-prize giveaway! Everything for the event is coming together nicely.

Sometimes I let myself get dragged down into self-pity or self-doubt. It consumes me. There's a name for a complex (I wish I could remember or find a link) where you're in constant fear that people will discover that you don't know what you're doing. I think we all go through it. In those times, I think it's important to take stock of what you DO have.

I just thought I'd share this in case anyone else is feeling overwhelmed or doubting their abilities. Stop. Breathe. Remember the good things you DO have and who loves you. It always makes me appreciate how sweet life really is, not just because the alternative sucks, but just because you have WAY more than you realize sometimes.

Okay "Chicken Soup" moment over. Back to the code.

~Lee

Originally, I had used JP's method from this MSDN article for connecting the Views and Presenters. It works very well except it leads to a lot of very similar code.

   1:  public partial class _default : Page, IDefaultView
   2:  {
   3:    private DefaultPresenter _presenter;
   4:    protected override void OnInit(EventArgs e)
   5:    {
   6:        base.OnInit(e);
   7:        _presenter = new DefaultPresenter(this);            
   8:    }
   9:    // other properties and methods for the IDefaultView interface
  10:  }
Then I came across David Hayden's article on the patterns & Practices web site and found the connective tissue I needed so that I didn't have 
to manually tell my presenter every time who the actual view was. It consists of a View Base class:
   1:  public abstract class View<ViewType, PresenterType> 
   2:      : Page where PresenterType 
   3:      : Presenter<ViewType> where ViewType : class
   4:  {
   5:      public PresenterType Presenter { get; set; }
   6:   
   7:      protected virtual void Page_Init(object sender, EventArgs e)
   8:      {
   9:          // could also use IOC container to handle this
  10:          Presenter = Activator.CreateInstance(typeof(PresenterType)) as PresenterType;
  11:          Presenter.View = this as ViewType;
  12:          Presenter.InitializeView();
  13:      }
  14:  }

and a Presenter base class

   1:  public abstract class Presenter<ViewType>
   2:  {
   3:      public ViewType View { get; set; }
   4:      public virtual void InitializeView(){}
   5:  }

then initializing my views like so:

   1:  public partial class _default : View<IDefaultView, DefaultPresenter>, IDefaultView

Seems to work very well. It may be old news to some developers, but it was new to me. Check out David and JPs articles.

~Lee