Readable Code Through Domain Driven Design

I went to a hands-on tutorial today by Eric Evans on Domain Driven Design. It’s one of those less specifically technical areas that is harder to pull off, but Eric made a pretty good effort with about 30 of us.

Domain Driven Design as presented is primarily the search for a good domain model through a ubiquitous language. The end result is that writing the code should really expressive of the underlying domain. Something like:

billDate.month().end().plus(allowedWaitBeforePayment)

In English this easily translates to:

For the end of the month on the billing date add a certain number of days before payment is due.

It’s still Java so it has some syntactic noise that’s hard to avoid, but it is approaching more readable code.

Some key ideas:

  • A model not reflected in the code is irrelevant. (ie MDA)
  • UML should mostly be done messy on a whiteboard.
  • Try to verbalize the concepts you describe in a model to eliminate awkwardness.
  • Not a big fan of getter/setter.
  • Primitive data types are bad. (float for money)
  • Business people will not use your modeling tool.
  • It’s OK tho have multiple models in different contexts if they have clear boundaries.
  • Object reuse often hasn’t worked well because sharing objects across different contexts. A person object who’s an employee in your financial system doesn’t actually carry over to a person object in your CRM system.

The class was thought provoking enough to nudge me to pick up his book on Domain Driven Design.

RSpec Tutorial Out of Sync

Just setting up my iBook for the next two days of tutorials at Software Development West 2006 and I ran across a familiar problem. Dave Astels is running the hands on tutorial on Behavior-Driven Development and using RSpec which he wrote in Ruby.

My notes say:

Attendees should be able to run the RSpec examples successfully before the tutorial.

So I’ve downloaded RSpec 0.4 and tried to run through the tutorial. The very first example is write the following expectation:

1
1.should_equal 1

And I get the following error:

1
undefined method `should_equal' for 1:Fixnum

After much experimentation I tried:

1
1.should.equal 1

And I get:

Finished in 0.037051 seconds
0 specifications, 0 failures

So I wrapped it up into a little class:

require 'spec'
class ExpectationsTest < Spec::Context
  def expect_one
    1.should.equal 1
  end
end

Then I happily get:

Finished in 0.017554 seconds
1 specifications, 0 failures

I’m guessing the the tutorial hasn’t been updated to the current release of the software. Another minor thing is that when you do the install and confirm that RSpec works by issuing the

1
spec

command. You’re suppose to see:

Finished in 0.002726 seconds
0 specifications, 0 expectations, 0 failures

Instead I see:

Finished in 0.021852 seconds
0 specifications, 0 failures

Somehow the expectations total is missing which makes me wonder if I’ve done something wrong. Anyway I think I have everything and I should get a much better feel for it after the tutorial.

Update, turns out that Dave did mention the should_equal changing to should.equal in this blog entry. Now the tutorial just needs to be updated.

Story Points Estimating

I was skimming through Agile Estimating and Planning by Mike Cohn. I’ve used his idea of story points in the past versus using ideal days to estimate product backlog items.

Story points are just relative measures of the effort involved in estimating a user story. We write up use cases and not user stories, but the idea is generally the same since we’re often estimating the ‘happy path’ of a use case or one of the major alternative paths on our product backlog.

Ideal days are assuming you had uninterrupted time to work on a task and you had everything you needed at your fingertips how long would it take. It’s a little more concrete then story points, but the lingering issue is that ideal days assume a duration.

Mike uses an analogy about ordering at a new restaurant. Generally you don’t know any of the exact sizes of items. You can:

  • Order a small, regular, or super size drink.
  • Order cup or a bowl of soup.
  • Order the lunch version of the pasta or the regular entree.

None of these items gives you any exact measure of the size or even how many ounces are in the drink or how much larger or smaller the lunch version is. Still you can very easily order the right amount of food without knowing anything but relative sizes.

At the end of the day though I prefer the story points approach. Story points are a pure measure of effort.

Ideal days bring with them the baggage of time durations. Since things are measured in days there is always the temptation to think about them as durations and forget about the fact that they are supposed to be ideal days and not actual days. Observers to a project may find this to be the most troubling as they can easily get the mistaken idea that the team is underperforming given the number of days the project should get done in.

The other big downside of ideal days is that it potentially reinforces troubles developers have estimating already. Many developers are tilted towards optimistic estimates. My rule of thumb when a developer gives me an estimate is to simply double it, because they are thinking in their own semi-ideal days. After I know a developer better I tend to adjust, partially because there are a few other developers who estimate very pessimistically so that they aren’t ever in danger of missing a deadline. Anyway, keeping them thinking about days instead of ‘Adding an Approval Workflow’ is about twice or three times more work than ‘Maintaining Employees’ breaks the connection to time estimating.

By default right now we’re using ideal days to measure product backlog items. I’ve used story points on at least two past unofficial Scrum projects, and I’m going to experiment with it again on the second sprint for our intranet portal.

Everyone Still Using Struts

Came across an interesting post via The Pragmatic Architect by Tim Fennell on Everyone and their dog is using Struts. He has a list of reasons why:

“Managers/developers are not aware of the alternatives to Struts”

I think most managers in corporate IT shops realize there’s options beyond Struts. At least the monster hype around JSF should have reached them.

“Struts is dominant so it must be the way to go”

This is a strong argument in it’s favor. Out of all the java web frameworks its still the leader despite the dustiness of age.

“Availability of developer who know Struts vs. perceived ramp up time for something else”

Again this is pretty accurate. Inertia is pretty difficult to overcome.

“Absence of books, articles etc. on alternatives”

I think frameworks like Webworks have become a bit more compelling after having books published on them. Pretty much other than Struts and JSF there aren’t any java web frameworks with much in the way of books.

“Alternatives are not “better enough” to warrant changing”

This is the single most compelling argument for me. There still isn’t a clear successor to Struts. JSF was supposed to be, but it hasn’t really happened yet, especially the 1.0 release. The other frameworks might be a lot better, but they haven’t really taken off so you’re going out on a limb that you’ll build apps that a few years later no one understands.

“It’s a corporate standard/other apps already use Struts”

Yuk, corporate standards. This can be dangerous. On the other hand I continue to see third party commercial Java apps that almost always have their web interface written in Struts. If we buy those apps it is nice to have developers who understand how they work.

Adaptive Pair Programming

We actually have some pair programming going on within one of our current projects. It evolved pretty naturally and not as some grand plan. There were two developers, one feature to work on that has requirements, and one developer who needed more mentoring. They’re doing TDD and using mock objects. The mock DAO objects allow them to make more progress than relying on a JDBC interface to our legacy system. I may even get to pair with one of them tomorrow and write some tests as well as a nice Friday bonus.