THE UNDERGROUND

A behind-the-scenes look at the software, tools and technology that make Infovark tick.

Software Craftsmanship

I’ve been a bystander in the Software Craftsmanship movement so far. I’m not sure why. I like the idea of software craftsmanship. I’m just not sure what it means in practice.

I’ve read the manifesto and considered signing it. I agree with the aims expressed there. I’ve also read the blogs of those skeptical or confused about the manifesto. I can’t decide what to do about it.

The best overview of the software craftsmanship idea is Mark Levinson’s Call to Arms article on InfoQ. It describes software craftsmanship as a response to the typical coding grind, where just-barely-good-enough software is shoveled out the door as rapidly as possible.

I understand and appreciate the feeling; I’ve been there. I know how much it hurts to release bad products that frustrate customers. But I’m not sure the software craftsmanship community has a solution to that problem yet. It’s early days, though, and over the past few months I’ve discovered some interesting ideas about software craftsmanship.

Glimmerings of hope

Recently I listened to a Hanselminutes podcast where Bob Martin discusses professionalism in programming. Uncle Bob made three points that caught my ear. He said that programming professionals:

  1. Embrace testing. When making changes to code, software craftsmen hold to the principle first do no harm.
  2. Refactor always. This ensures flexibility in the codebase by “keeping the gears lubricated.” Be mindful of small improvements you can make to your software. This prepares the way for making bigger changes later.
  3. Learn continuously. Professionals practice their current skills and attempt to master new ones.

On the subject of continuous learning, I recently watched Mary Poppendieck discuss deliberate practice in a webcast on InfoQ. The summary: To become an expert in any field, you need to seek out coaches that teach the skills you need and spend focused time practicing those skills. Continuous learning is about gathering resources, understanding the material, and gaining experience through repeated effort.

After listening to these two programming mavens, I remembered something I’d read a while back on Coding Horror about code kata. Dave Thomas, of pragmatic programming fame, coined the term code kata for exercises designed to improve programming skills. He has a list of code kata, but other code kata catalogs have appeared as well.

From strategy to tactics to execution

So maybe there’s hope for the software craftsmanship movement after all. We’ve moved from talking about abstract goals to ideas we can put into practice. There’s a slow consensus building as to what a professional looks like and how one becomes a professional. That’s encouraging.

Ultimately, software craftsmanship isn’t about signing a pledge. It’s about delivering quality product.

Visual Studio 2008 and the CopyLocal setting

Though the Microsoft marketing drums have begun beating to the rhythm of Visual Studio 2010, most of us workaday code monkeys are still using Visual Studio 2008. And while VS 2008 is a great IDE for development — especially once you add ReSharper — it has a few configuration quirks that drive me up the wall.

Most of these quirks are hidden from the typical developer and only appear once you try to package and deploy your software. It’s the dreaded Works on My Machine syndrome.

And if there’s one Visual Studio build configuration setting that causes me to scream in anguish, it’s the CopyLocal property.

Feel my pain

When you add a reference to another .dll in Visual Studio 2008, some default settings get applied.

The CopyLocal setting on the reference properties panel.

The CopyLocal setting on the reference properties panel.

Here’s how the settings look after I added log4net to one of my projects. As you can see, the CopyLocal setting is set to True. Or is it?

If you move your solution to your build server, you might be surprised to find that CopyLocal isn’t actually copying the .dll. I was certainly surprised to find that my builds failing for inexplicable reasons.

It took me a while to figure out that Visual Studio 2008 is a dirty liar when it comes to CopyLocal. Let’s have a look at our .csproj file, shall we? You can load the XML in the .csproj file by following these directions.

Ah, there’s the contents of our csproj file. And there’s our reference to log4net, but…

Where's the CopyLocal setting?

Where's the CopyLocal setting?

The CopyLocal setting isn’t there! Within the log4net reference, we should see an XML element called Private. It should look like this:

  1. <Private>True</Private>

But it’s clearly not there. Uh oh.

And because it’s not there, it might work on your machine but not on other machines. Even though the Visual Studio IDE represents CopyLocal as a Boolean value, it’s actually a ternary value. Where Booleans have two states, usually represented as True/False, Yes/No, or 1/0 pairs, ternary logic has three states:

  • True
  • False
  • Um… uh… Other?

Yikes! That’s a classic interface failure mode.

It turns out that the default for the CopyLocal setting is… something not quite True and not quite False. If you read the documentation for how to set the CopyLocal property, it mentions the weird logic Visual Studio uses to determine what the “default” should be. Argh.

Manual repairs

To fix the problem, we reload our project in Visual Studio again. Then we toggle the CopyLocal setting from “not quite True, exactly” to “False” and then back to “totally, literally True”.

With apologies to the Violent Femmes, when I say CopyLocal, you best CopyLocal, motherf***er!!!

And now it’s really, truly TRUE. Honest. Take a look at our .csproj file now.

This is how CopyLocal=True ought to look.

This is how CopyLocal=True ought to look.

And there it is, the CopyLocal setting. The way it should be. The way it should have been all along.

Conclusion

I don’t know whether Visual Studio 2010 fixes this problem. I haven’t looked at the VS 2010 Beta release to find out. I’m too busy manually editing all my .csproj files to get our Infovark builds working. But I really, really, really hope that the folks at Microsoft have done something to address the problem.

Here’s the simple interface design rule: If it isn’t a Boolean setting, it shouldn’t look like a Boolean setting.

Unless of course, you want to make the pages of The Daily WTF.

Writing to the Future Me

Every now and then I find a comment in my code that I’ve completely forgotten about.

When I run across one of these nuggets, I guess I have the same experience as someone who’s kept a journal for months or years. I read the note and think, was that me that wrote that? Did I know that I would come back here again? Was a sending a message to my future self?

// TODO: Improve the quality of these tests. DTHRASHER 6OCT2008
// We need to verify that the filter string is being generated properly.
// We need to add tests to verify sorting behavior.
// We need to separate the ActivityParameters unit tests from the MetaIndex integration tests.
// We need a staff of 10 developers to help us finish this product! ARGH.

These always give me a chuckle.

And then I think, what a jerk that DTHRASHER guy is! I can’t believe he left me all this work to do!

Domain Models in High Performance Systems

I skipped today’s DC Alt.NET meeting on JavaScript. With the other half of the Infovark tech team on vacation, I’m holding down the fort.

Fortunately, I was able to expand my programming knowledge by catching up on my blog reading, and particularly by watching Greg Young of IMIS give a presentation called Unshackle Your Domain at QCon in June.

If you’ve ever had to built a high-performance system or one that has strict auditing and reporting requirements, this presentation is for you. Greg’s company deals with financial systems, and you can tell he’s learned many best practices the hard way.

While I doubt we’ll need an architecture as robust as he describes for Infovark, I recognize many of the the problems and patterns he describes from my old jobs in software companies making records management software (auditing) and real estate systems (transactions and reporting).

The key insight is that for certain software solutions, it’s important to model state transitions as part of the problem domain.

But what I found most interesting was how his example system combined the principles of Domain-Driven Design with the older notion of Command-Query Separation.

I’d explain in more detail, but it’d probably be easier to just watch the presentation yourself.

Laughing in the Face of Errors

To a human, “I once met a man with a wooden leg named Smith” is the start of a old joke. To a computer, it’s a compile error.

Class 'WoodenLeg' has no 'Name' property or the property is not accessible.

If only computers had a sense of humor…

Validation in Domain Driven Design

There’s a great discussion on Jeff Palermo’s blog about entity validation patterns. Jeff takes the position that your domain objects (or entities) should not have validation logic “baked-in” to the class itself. Instead, you should separate the validation routines into separate classes that you can use to validate the object on demand.

There are two advantages to this approach. The first is that you can use different validators for the same object in different circumstances. For example, the validation you might perform prior to storing the domain object in a persistence layer could be different than the validation routine used to validate input from the GUI layer.

The second advantage is that separating the validation logic from the data itself makes it easier to work with ORM or serialization frameworks. Most of these frameworks encourage the use of Plain Old Objects, that is, objects without special attributes or interfaces that help with these mapping and serialization tasks. (See Wikipedia’s article on Plain Old Java Objects, for example.)

Those are powerful arguments, but I’m still not convinced.

Trade-offs

As a practical matter, Jeff’s advice is sound. It’s much easier to move business logic into the helper classes that surround your entity model. You get better tool support and more flexibility. But there’s two things about his approach that bother me. Judging by some of the excellent comments on his article, other programmers are bothered by them as well.

First, stripping away behavior from your domain objects is a recognized anti-pattern in object oriented code. Martin Fowler calls it the Anemic Domain Model. It harkens back to the days of procedural programming, where data and business logic were strictly separated. If you’re an OO purist, this is a red flag.

From an OO perspective, the need to validate the same object in different ways suggests that what you actually need to do is create more objects. Rather than pass a stripped-down data-transfer object (DTO) all the way from your data storage layer up to your GUI, you should have a bunch of intermediate objects to help transition the data and enforce proper behavior.

But I’m not an OO snob. Writing a whole bunch of extra classes to move information between tiers in my application is a hassle. I’ve done it before, and we’re doing it now with Infovark, but for most projects it just isn’t justified. Especially if you have to wrestle with various application frameworks to deal with correctly modeled but more complicated domain objects.

The second objection I have is that if we follow Jeff’s advice, we have to accept that bad data will creep into our domain. Jeff knows that this is a hard sell. It’s why he titled his article “The fallacy of the always-valid entity.”

Whew. That’s rough. That requires a whole different programming mindset. What about the problem of Garbage In, Garbage Out? Can we really create programs robust enough to handle business objects that might, at any moment, contain meaningless gibberish?

I don’t know. For now, as appealing as Jeff’s idea is, I’ll stick to always-valid approach. What do you think?

Review: Framework Design Guidelines

Framework Design Guidelines

I’m almost embarrassed to admit that I really enjoyed Framework Design Guidelines by Krzysztof Cwalina and Brad Abrams. I mean, it’s a book about coding standards.

Maybe I ought to get out more… but before I leave the glare of my monitor behind, I’ll type up my review.

Code is literature, not language

Computing languages, just like human languages, have grammar and syntax. There are correct ways to form sentences and paragraphs, with well-defined rules (and exceptions). Just like word processors can check spelling and verify basic sentence structure, most IDEs today can ensure your code will compile and run.

That doesn’t mean that your story or program is an easy or enjoyable read, though. Most newspapers have accumulated extensive guidelines for matters of style and substance, and most software companies have their own guides as well. If you’re writing as part of a team project, or writing programs intended to be used by other programmers, it’s important to make your code consistent, clear, and direct.

Just like many journalists keep a copy of The Associated Press Stylebook or the New York Times Manual of Style and Usage handy — even if they don’t actually work for the New York Times or the AP — lots of programmers keep a copy of Microsoft’s Framework Design Guidelines as reference.

Or they should. That’s probably my roots as a maintenance programmer showing.

Know your genre

Ideally, you’d want any code you write for other Windows programmers’ use to look as if it came from Microsoft itself. That is, you want it to feel like a natural extension of the .NET framework and not some third-party bolt-on with odd stylistic touches. You’d also like your code to use the full power and expressiveness of .NET, and not appear like some watered-down Java-esque port. (Far too many open source projects retain awkward Java-isms after being converted to .NET, in my opinion. NUnit is a notable exception.)

This helps your fellow programmers gain a better understanding of your code in less time. And it can also make your programming tasks easier, too. Just like design patterns can help you lay out your application architecture, programming guidelines can help you structure your code at the class or method level.

About the book

The Framework Design Guidelines covers a lot of ground in its 400 pages. It describes what conventions Microsoft uses when designing types, methods, and exceptions. It also describes the naming and design patterns that Microsoft uses in their public APIs. The topics are grouped by category and heavily cross referenced, making it easy to find your way around. The rationale of each guideline is explained, and the authors indicate the strength of each recommendation by marking it with the terms Do, Consider, Avoid or Do Not.

But the best part of the book is the stories and comments given by members of the Microsoft team. These are sprinkled throughout the book and give insight into why the guideline exists. Some of these discuss lessons Microsoft learned the hard way, places in the .NET Framework where the rules are violated, and how real-world programmers feel about certain guidelines. You can get a flavor of these by checking out the Framework Design Guidelines section of Brad Abrams‘ blog.

If you find his posts interesting or helpful, you’ll feel the same way about the book. Highly recommended.

The Times, They Are A-Changin’

Recently, I made a plea for the adoption of Universal Coordinated Time (UTC) in computer applications. It’s a sensible recommendation, and I stand behind it.

The folks working on HTML 5 are proposing a <time> element for the new standard. This makes sense to me. It will help eliminate some of the objections people have raised to the datetime design pattern proposed by the microformats team.

So, problem solved, right? We use UTC for time, and the usual calendar notation for dates. Neat.

Wait a minute. By “the usual” calendar notation, do we mean the modern Gregorian calendar, or…

There’s always a catch

Peter-Paul Koch, a.k.a. PPK, author of the quirksmode blog, reminds us that calculating historical calendar dates is hard. Really, really hard.

He provides an overview of the major calendar reforms in the Western world and points out that the reforms were adopted by different countries at different times. So forming a consistent timeline requires a knowledge of both time and place.

And many important historical dates float. The rules that determine when Easter occurs in the church calendar are complicated, and Orthodox and Catholic calendars disagreed for many years. In the medieval period, years were often numbered according to the local monarch’s reign. In Roman times, extra days were added to the official calendar by decree to prevent the seasons from drifting too far out of line.

If we want to make the <time> element safe for historical use, programmers would have to deal with this mess.

Leave it to the historians

As useful as having universal, consistent <time> element metadata would be, that’s just too hard. Frankly, I skimmed the last bits of PPK’s article myself, and I’m actually interested in the issue. Most working programmers won’t bother.

While it’d be nice to have trustworthy time data, we’re not likely to get it. The standard should reflect that. I vote for assigning a cutoff date for the <time> element. January 1, 1970 works for me.

Tools: Firebird Maestro

I didn’t set out to buy a SQL IDE three months ago, but I bought Firebird Maestro from the SQL Maestro group anyway.

What I was looking for

What I was actually looking for was an equivalent to Red Gate’s SQL Packager for the Firebird database. SQL Packager is a useful application that makes it easy to package and deploy database schema upgrades. Sadly, all of Red Gate’s tools are for Microsoft SQL Server only.

My next step was to look through the list of admin tools on the Firebird website. And while there’s a huge selection of tools available for Firebird, I couldn’t find anything that would help me deploy schema and data upgrades. It was a bit surprising, actually, since one of Firebird’s strengths is how easy it is to embed inside other software applications. (If I’ve missed an application that can do this, please let me know!)

What I found instead

During the course of my investigations, I downloaded several different tools for managing Firebird. I’m a fan of the fast and free FlameRobin, but it’s still in development and doesn’t do everything I need. Sometimes a full-featured IDE is required, and I found two that fit the profile.

The first was SQL Studio from EMS Database Management Solutions. I appreciated their customer support and the breadth of features. But ultimately, I decided upon Firebird Maestro. The differences between the two IDEs were small, but Firebird Maestro had a better tool for producing database diagrams. Since Infovark has developers working halfway around the world from each other, having a good database diagram to reference is a must. Firebird Maestro also had a simple wizard for scripting out the schema and data into a single file. We put this text file into Subversion so that we have our database structure under version control.

Firebird Maestro

Firebird Maestro

It won’t help me deploy an update, but I’ve had to do that sort of thing by hand before, and I suppose I can do it again. But sometimes when you look for something you find something else just as good.

Visual Studio 2008 and its CopyLocal setting

Our build server wasn’t producing the same results as our local development machines. The same C# code yielded two different sets of code libraries. After much head-banging and hand-wringing, we finally traced the problem to an obscure error in the way Visual Studio 2008 handles .csproj files.

Basically, the Visual Studio IDE doesn’t handle the CopyLocal setting properly. This post from paraesthesia set us on the right track.

I have no idea what caused the problem. We had the same versions of the .NET Framework and Visual Studio 2008 installed on all our machines. The code was exactly the same. Apart from the build machine being Windows Server 2003 and out development machines being Windows XP, I can’t think of any other differences. But somehow the code libraries weren’t getting copied in the same way.

Just another adventure on our way toward the Beta release…