3

So I'm working on a software product where we have a number of fields that the customer can leave blank, some of which are numeric. To persist these in the database we use nullable columns. Easy peasy.

I'm considering the utility of an object oriented domain model and one thing that bugs me is the issue of nullable fields.

The reason is, in the world of Java and C# one often finds advice against having null values and indeed writing code with null checks all over the place sucks. And then you get null reference exceptions when you forget to check for null. And it's a mess. So a "good" approach is to initialize everything when you declare it.

Now, the idea of null actually makes sense for these fields... the customer did not enter a value thus it has "no" value (not 0, not -1, etc). But application programmers and programming languages seem to be configured for binary rather than ternary logic, and also for variables just darn well having a value rather than maybe having a value but also maybe not.

With object oriented design I presume one could come up with some clever system of representing cases where there is "no" value but I personally haven't done the analysis yet and the reason is I find incremental change more successfully sells to people than radical change does, so proposing an object oriented domain model that's "too object oriented" might kill the idea and thus my hopes of improving the structure of our software. I'd rather propose a "version 0" domain model that works and is easy to sell internally... and so this whole thing about null values weighs heavy on my mind.

Since we are using C# I could just define nullable numbers, its very easy one just adds a question mark. But I'm not convinced that just because it's possible it's also the best approach.

So, with all this background junk out of the way my question is: how have you/your company handled "nonexistent" values in an object oriented domain model, in what ways did you find it effective and in what ways did you find it ineffective?

My selection criteria for the "answer" will be the one that seems most "sellable" as defined in the background junk. But really I'd like to see what people come up with and learn some new things so any answer with some thought behind it will receive an upvote from me.

Note: I've seen other discussions about null values in other threads but nothing that quite lines up with what I want to talk about, hence a new question.

EDIT: My question's scope includes value typed properties like numbers. So in C# one way to allow for representation of a null purchase price would be to declare "PurchasePrice" as "decimal?" which is the nullable decimal type. I just see a number of disadvantages to numbers (for example) that can also be null, so I'm looking for an alternative.

EDIT 2: The Null Object Pattern makes sense for references, and using a nullable type for values appears as if it may be tractable with coalescing. What bothers me about coalescing null types is "what if someone forgets to coalesce and we're exposed to a null reference exception?"... and I suppose I could maybe use a static analysis tool which ensures that coalescing is used where expected to allay that worry.

EDIT 2': In a sense, if someone has made a conscious decision to make a field nullable they are adding the ability to represent an extra piece of information that would otherwise need another field to represent it such as a boolean HasValue. Does that mean the "anti-null" zealots I've met in the past were perhaps incorrect, and measured use of nullity can in fact improve a design?

3
  • Nulls have their value, especially as a poor man's Maybe. The problems with null are that it doesn't compose well, and that some languages allow nulls where it doesn't make sense. If you have a case where they do make sense, either use them, or use the null object pattern.
    – amon
    Commented Jan 30, 2014 at 16:53
  • You might also find null coalescing in C# a nice way to do checks. Commented Jan 30, 2014 at 17:08
  • @VaughanHilts yes, this is something I have "heard of", but looking into it the syntax is pretty clean. In a sense, if the domain model defines X to be nullable then a presentation component could use coalescing to cleanly supply a representation of that null value. It's almost like MS wants us to use nulls :P
    – Paul
    Commented Jan 30, 2014 at 17:38

2 Answers 2

2

I think you are mistaking something here. The problem of null in languages like Java and C# is that reference types are null by default. Eg, the null is implicit. That means there is no way to express idea of reference type always having a valid value. You always have to check for null. Even if you are sure the value cannot possibly be null, the Murphy's law says it will happen sometime, so checking is necessary. There is no way to have compiler do the checking for you. Of course there are ways like code contracts, but those are relatively new in those languages and require additional work from developer to do right.

The way Nullable value types work is exactly how it should work. The compiler knows there is one additional state and knows how you work with the variable. So it can create an error when it sees there is possibility dereferrencing this null state. For example, you cannot add Nullable<int> and int simply because compiler knows there is possibility of first value being null. So it forces you to do the checking before hand. Even simple assignment from nullable to non-nullable type is checked by compiler simply thanks to it's type. No such thing is possible for reference types. Of course there is problem of programmer just adding .Value to every access and be done with it, but that is problem of programmer's discipline that no tool can fix.

Summed up. Your worries about nullable value types are completely unjustified because null is only problem when it is implicit and compiler cannot check for possible errors of accessing null value. Which is not the case of Nullable value types.

2
  • Your characterization of the problem with reference types compared to nullable value types makes sense. I think maybe the right approach for me is to make fields nullable in the domain model if there was a good reason for the db field to be nullable in the first place at which point the null check is, rather than an irritant, a check for some condition that has relevance in the domain. The fields that are nullable for no good reason can be made non-nullable and the database can have default values from my code rather than nulls.
    – Paul
    Commented Jan 30, 2014 at 19:06
  • 1
    The clarification this answer has provided I believe has given me the understanding I need to tackle the original problem, and therefore I will mark this as the answer.
    – Paul
    Commented Jan 30, 2014 at 19:11
-1

There is a pattern called NullObject.

The only reason why I would say this can sell is that your tests whether this object is NUll or not are in the NUll object and thus... When your software grows there is exactly one place to look for NULL-value-behaviour. Code duplication is removed suppose:

function1(x) {
    if x is NULL {
        handleit(x)
    }
}

function2(x) {
    if x is NULL {
        handleit(x)
    }
}

The two functions are in a different location or class so the handleit(x) can not be reused (forgotten/typechecks) if it is not in the Null-Object.

There are other people to reason about software quality and why it is good. Be aware that your design decision is about your developers now and future developers.

I used this pattern once and it worked quite well. I think if you answer the following question with yes then the Null Object is not too far from your choice:

Should the code that affects the object be in the object?

Edit1: value types

Seeing http://msdn.microsoft.com/en-us/library/ms173104.aspx you can create own value types. So you can create own value type null objects. Value types are an optimization of the programming language. For code pieces where optimization is necessairy you can use them. And otherwise use the reference types.

8
  • 1
    I hadn't heard of the Null Object pattern and this is certainly useful, however it appears to address reference types only whereas I am interested in addressing reference and value types.
    – Paul
    Commented Jan 30, 2014 at 17:14
  • As soon as my reputation reaches 15 I will upvote this... having just started here at Programmers I find my self a little more restricted than at StackOverflow :P
    – Paul
    Commented Jan 30, 2014 at 17:15
  • I am more in favor of code quality than performance. So for this I am the wrong address. If C# does not let you modify value types or create new ones then you can not have both.
    – User
    Commented Jan 30, 2014 at 17:21
  • Until you mentioned it just now it didn't occur to me to define my own value types but I suppose I could... but then I suppose I'd have a Nullable<T> and then would have reinvented the wheel. So if I'm clear about everything (which isn't always the case) you might advocate null object pattern for reference types plus using the nullable value types?
    – Paul
    Commented Jan 30, 2014 at 17:35
  • I can not speak for value types. I never used them. Please find out how you can implement a solution with or without them and let us know!
    – User
    Commented Jan 30, 2014 at 17:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.