Special Case
The special case pattern
The special case pattern is a move away from the standard design patterns and approaches the issue in a number of programming languages. Now before I write this I have to explain that I really don't know what to do either. I've read a number of articles online and alot of programmers feel very strongly about this, some believe null is fine and others believe it isn't and get quite agressive if you suggest they could be wrong.I'm going to take an objective approach as I'm interested in reducing complexity and improving design, therefore if I remove null (somehow?) then is my design better or vice-versa?
Ok, so we've all seen and had to type out, thousands of times, something similar to the following:
class IndividualProcesser {
private Individual individual;
public IndividualProcesser(Individual individual) {
if (individual == null) {
throw new ArgumentNullException("individual");
}
this.individual = individual;
}
}
The if (individual == null)... check for null is what I'm talking about.private Individual individual;
public IndividualProcesser(Individual individual) {
if (individual == null) {
throw new ArgumentNullException("individual");
}
this.individual = individual;
}
}
Microsoft have come up with a few different ways to protect against the null, I can't keep up with them, but I think the last idea was a comma, comma, fullstop, question mark...or whatever! But it didn't solve anything.
There's also aspect orientated where I can put a [NotNull("individual")] or something similar above my code and reflection is used to do the null checks and the appropriate code inserted at compile time (or maybe runtime but this would be slow).
Now one of the issues with not having null is that I have to think of a default behaviour and if I make a null object then I have to have told all the developers from that day forth about my ingenious plan even when I've left the company. Hmmmmm this is difficult!
Lets go back a bit to an immutable DTO:
class Individual {
public int Id { get; }
public string FirstName { get; }
public string Surname { get; }
private Individual(int id, string firstName, string surname) {
Id = id;
FirstName = firstName;
Surname = surname;
}
public static Individual CreateIndividual(int id, string firstName, string surname) {
return new Individual(id, firstName??"", surname??"");
}
}
Ok I have to admit I've made a disasterous attempt at solving the null problem here!
But I had to start somewhere...public int Id { get; }
public string FirstName { get; }
public string Surname { get; }
private Individual(int id, string firstName, string surname) {
Id = id;
FirstName = firstName;
Surname = surname;
}
public static Individual CreateIndividual(int id, string firstName, string surname) {
return new Individual(id, firstName??"", surname??"");
}
}
I'll change my CreateIndividual back to something more predictable:
public static Individual CreateIndividual(int id, string firstName, string surname) {
if (string.IsNullOrEmpty(firstName)) {
throw new ArgumentNullException("firstName");
 }
if (string.IsNullOrEmpty(surname)) {
throw new ArgumentNullException("surname");
}
return new Individual(id, firstName, surname);
}
Oh no, that's so ugly what if it was more complicated (I'm sure you've seen 100 line database columns)!if (string.IsNullOrEmpty(firstName)) {
throw new ArgumentNullException("firstName");
 }
if (string.IsNullOrEmpty(surname)) {
throw new ArgumentNullException("surname");
}
return new Individual(id, firstName, surname);
}
Maybe I should make a static utility method or, as I've mentioned, an aspect to sort out this insanity!
Let's try the special case pattern, to our current Individual class, we add a private class eg:
private class NullIndividual : Individual {
public override string FirstName { get => throw new ArgumentNullException("FirstName"); }
public override string Surname { get => throw new ArgumentNullException("Surname"); }
public NullIndividual() : base(-1) {}
// or
public static NullIndividual Null = new NullIndividual();
}
we need to add and extra private constructor to Individual:
public override string FirstName { get => throw new ArgumentNullException("FirstName"); }
public override string Surname { get => throw new ArgumentNullException("Surname"); }
public NullIndividual() : base(-1) {}
// or
public static NullIndividual Null = new NullIndividual();
}
private Individual(int id) {
Id = id;
}
My special case sets the id as -1 and if you try to access the
FirstName
or
Surname
properties then you'll get an exception (as they're null!).Id = id;
}
Maybe I should redefine the string class to not allow null or could I just have an empty string?
I'm going to leave this argument as everything is getting more and more complex and I'm just trying to handle a null!
Summary
I left the argument a little bit flat as I have no answer. I could add a null check method to the
Individual class but this is just adding more complexity.
I have to admit I'm not really one for conventionality but I think I'd stick to the throw an exception
when the value is null to warn the next developer that this value can't be null.