One of the interesting things about writing a book is that you get email for years afterward. And, it’s better than most email. No one who has read your book is trying to sell you Viagra or refinance your mortgage. In general, all of this new email centers on mistakes you’ve made, or things people have thought while reading your book. It’s like a long term, low-tech RSS feed with lots of goodies. It just goes on and on.

A few weeks ago, Christian Brandt contacted me and told me about something he’d done that would’ve made an example better. It centers on the use of Special Case objects.

Special Case is a pattern that Martin Fowler wrote up in Patterns of Enterprise Application Architecture. The idea is that sometimes we need special behavior and we can achieve it by taking the interface of a particular class and providing a special implementation for it. This is all pretty vague. Let’s look at an example.

In my book, I wrote up an example that dealt with duplication removal in a class hierarchy. It had two classes LoginCommand and AddEmployeeCmd. Over the course of the example, I pulled duplication up into a superclass called Command. The command classes are responsible for rendering bytes to a stream so that they can be transmitted across a wire. Commands are variable length, and the size of each packet is sent within the packet so that it can be decoded and checked on the other side. Now, the way that I handled this was to have a getSize method on the Command class. The getSize method calculated the size of all of the fields that were going to be sent, and it was called by a method named write, which did the actual write upon the stream.

So far, so good.

Christian’s idea, one I’d never seen in this context, was to make another class, one that behaved like an output stream, and did nothing more than count the bytes sent to it. Since this class acted like a stream it could be passed to the write method. At the end of its use, it could tell you exactly how many bytes would be sent when a real stream was used.

Here's what it would look like in Java (Christian wrote it up in C++):


public abstract class Command 
{
    …
    public int getSize() {
        NullOutputStream stream = new NullOutputStream(); 
        write(stream);
        return stream.getNumberOfBytesWritten();
    }
}

Christian used the name NullOutputStream, and it’s true, this object is a bit like a Null Object, but it is different. It isn’t intended to do nothing; it’s intended to do something, albeit something very different than a normal output stream.

I’d be tempted to call it ByteCountingStream:


public abstract class Command 
{
    …
    public int getSize() {
        ByteCountingStream stream = new ByteCountingStream();
        write(stream);
        return stream.getNumberOfBytesWritten();
    }
}

And, in fact, we don't even need to create a new class to do this in Java. We can hijack an existing one: ByteArrayOutputStream if we don't mind the overhead of adding bytes to an array.


public abstract class Command 
{
    …
    public int getSize() {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        write(stream);
        return stream.size();  // returns the number of bytes written
    }
}

This is a particularly elegant way of handling things. Rather than having separate code to traverse writable things for size and write, all of the work can be done with the same piece of code, the write method. There’s less duplication and less possibility of error in maintenance.

Few people see opportunities for Special Case objects. I think that there are a number of reasons why. On the one hand, they are a bit tricky. I’ve worked with people who actively dislike Special Case objects and Null Objects because they feel that they are deceptive. While that’s true to a point, it’s also true of many of the original design patterns – Composite deceives you into thinking that you’re dealing with only one object when you are dealing with many and Proxy deceives you into thinking that you’re dealing with one thing, not another – but, that said, Special Case and Null Object seem particularly tricky unless you're used to them. They are kind of like polymorphic puns.

Another reason why people don’t use Special Case is because they haven’t heard of it, but I hope that changes.