Wednesday, October 11, 2006

Command Pattern

Jeff wrote commenting about one of my posts on validation:

I also like the idea of just having an isValid() method type solution. I did a 1 day spike on our Well class to look at implementing our validation as separate business rule objects. This way, you can easily validate based on a given context, so you could have different rules be applicable during creation vs during an update (as an example).

I was particulary inspired by this post:
http://www.jpboodhoo.com/blog/ValidationInTheDomainLayerTakeOne.aspx
This comment made me think about the command pattern and its applicability to different problems. The basic idea of the command pattern is to convert a function into a full-blown class. You can read more about it here on wikipedia. I've used the command pattern in a number of projects in the past. Here are a couple of examples: On one of my projects, users were able to choose from a number of batch processes they wanted to run, either to load data or to do diagnostics on large recordsets all at once. In general there were several hundred thousand records processed by each such batch job. Another developer started off by writing code that implemented each process as a function in a large class. This was an oil and gas application, so he had functions like loadWells(), loadPools(), etc... all in one class. There was a lot of duplication from one function to another and the code was messy, so one of the first things I did was to refactor it into the command pattern. I turned each loading process into a class that implemented a single method, execute. For example, I had a WellLoader class, and a PoolLoader class that both extended a BatchProcess abstract base class which exposed an abstract execute method. The base class also exposed some protected methods that permitted, among other things, a progress indicator during batch processing (since each batch job generally took several hours). When users selected which batch processes they wanted to run, the system would create an instance of each job and add them all to a list, then successively called the execute method on each one. Whatever the details of implementation of each batch process, its only public interface consisted of the methods in the BatchProcess class, primarily the execute method. Another case where I used the command pattern was an embedded system in the scada world that did scheduled polling of sensors. In this case I took advantage of the command pattern to schedule and execute different kinds of polls and alarms. I set up each poll or alarm one as a different class. The scheduler class would loop through each process in its queue and if it was time to run that process, it would call its send method.

In Domain Driven Design, Eric Evans shows how the command pattern can be used to create specification objects. Such objects can be chained together to validate constraints, create objects, or filter lists. I think the example Jeff presents above falls into this general category. It's an interesting idea, but I think some caution is warranted, because the goal of patterns is to simplify code and reduce duplication. If validation rules can re-used or need to be chained together and executed in different combinations at different times, then it makes sense to use the command pattern. However, if validation rules are always applicable to a given domain object and are not re-used between different classes, then maybe the less flashy approach of just making each validation a method in a Validator class is more readable and good enough.

On a quick final note, I recently read Jamie Mcilroy's post about JSF validation. It seems as though JSF binds the gui directly to a domain object and invokes validation separately for each form field. I don't know how much I like that. I think I'd rather JSF invoked validation on the whole domain object in one call and used keys to determine which form fields had errors. Anyway, given the way it seems to work, that might be a good opportunity to take advantage of Jeff's idea of making each validation a separate class. That way, each attribute validation can easily be invoked from JSF but still be indepedent from the JSF framework itself.

Tuesday, October 03, 2006

Defensive Programming: Handling Nulls

C was one of the first languages I learned to program in. In C, you access memory direcly with pointers and it's not unusual for bugs to arise from improperly dereferencing those pointers. This generally causes the application to crash, often with a segmentation fault or bus error, and sometimes the application manages to carry on, overwriting memory until it finally fails, often in a way that is very difficult to reproduce or track down. Accessing memory directly certainly gives the maximum amount of control, but it's also very error-prone. In managed/interpreted environments, like Java, C#, Perl, Python, or Ruby, one can't access memory directly. Instead, the runtime environment interposes a handle to an object or structure. This prevents most of the memory problems that arise in C applications. However, there is still the problem of using references that don't point to any particular object. These are called null references, or nil references, or something along those lines. In Java, when you call a method on a reference that doesn't point to any object, the runtime throws a NullPointerException. I'd rather it throw something like a NullReferenceException, but that's neither here not there :). It's not nearly as bad as having memory problems in C, because you can trap these exceptions and then your application can carry on, but it doesn't improve user confidence, and it leaves parts of the application inaccessible to the user.

One of the ways to handle such exceptions is called the Null Object pattern. basically, the idea is to guarantee that a reference to a particular kind of object will always be initialized with a stub that implements some kind of harmless do-nothing behaviour for that type of object. The idea is to guarantee that an object will always be there when you call a method on an object reference. Let's say your application involves keeping track of customers. If you search for a customer with an invalid id, instead of returning null, you'd get back a Customer object. If you try to call any methods on this object, they will either do nothing or return intelligent defaults. For example, getAge() would return 0. This is a useful pattern, but there are some issues to keep in mind. First of all, there will always be cases where one must distinguish between a real object and a null object stub. This is generally done by implementing an isNull method for all domain objects (in Java, you could create a Substitutable interface for this purpose). This isNull method will only return true when executed on Null objects. Secondly, defining the proper do-nothing behaviour for complex domain objects can lead to overhead. In an example below, I will try to show an what might need to be done to rigorously implement Null Object. Also, If you want to use the Null Object pattern, you should adhere to the Law Of Demeter to avoid having to implement a whole bunch of un-necessary Null Object types. In other words, instead of having something like student.findExam(3).getGrade(), you would simply call student.getGradeForExam(3). This approach makes the Student class easier to turn into a Null Object. If you tend to be checking object.isNull all the time, then maybe this pattern is not the right one to use, since it is designed for cases where most of the time, you are ok with the Null Object's default behaviour. Finally, I'm not sure it's possible to always define proper do-nothing behaviour that won't depend on some context, though I can't think of a real case of this problem at the moment.

Here is an example I've tried to cook up to show what Null object implemented
throughout an application might look like (it's Java code, as usual, since that's
the language I feel most comfortable with).

public interface Substitutable {
public boolean isNull();
}

public abstract class NullObject implements Substitutable {
public boolean isNull() {
return true;
}

public boolean equals() {
return false;
}
}

public abstract class DomainEntity implements Substitutable {
public boolean isNull() {
return false;
}
}

public interface Customer {
public String getName();
public void setName(String name);
}

public class CustomerImpl extends DomainEntity implements Customer {
public String getName() {
return name;
}

public void setName(String aName) {
name = aName;
}
}

public class NullCustomer extends NullObject implements Customer {
public String getName() {
return "";
}

public void setName(String s) {}
}


Note the extra overhead of an interface for each domain class needed (at least in my example) to more easily support NullObject. To introduce methods in Customer that return proper domain entities rather than value objects like String, I'd have to provide NullObject support for those as well! Also, I've implemented default behavour for equals method to always return false. I wonder that the right behaviour for hashCode might be. Hmmm. It's definitely a bit of extra work. Is it worth it? I haven't ever tried this approach so I'm not really sure.

While the Null Object pattern can be helpful in eliminating null exceptions, it has to be implemtented judiciously throughout an application. Another approach I tend to use to prevent having to check for nulls all over the place, which I haven't seen on too many other projects, is to write static utility methods for many standard operations that compare two objects in some way. For example, one often finds code like if (a != null and a.equals(b)) - I suggest replacing that with if (Util.equal(a,b)). Here is how I implement the Util.equal method:
 public static boolean equal(Object a, Object b) {
if (a == null || b == null)
return false;
return a.equals(b);
}
Again, if a were a Null Object, it would implement the equals method by just returning false.

Other ideas include numeric comparisons on non-primitive numeric types, e.g. isZero(Number a), isLessThan(Number a, Number b), etc..., date comparisons, and so on.