µObjects: No Nulls

Maintainability By Refusing null

Our goal as software developers is to produce code that can be easily maintained. This is frequently a challenge; as writing good code is hard.
µObjects is a way of Object Oriented Programming that I've found gives us this. There are a number of ways that µObjects improve the maintainability of code and the elimination of null is what we'll look at today.

µObjects strongly discourage null; as a proper µObject is to never return null. µObjects also require protection from nulls getting into the code. At the bookends; handle any null. Create some form of a null object; or fail. Don't let any nulls into the system; as they'll cause problems.

The null mistake ... something something billion dollar mistake something something. Don't much care; null is a giant pain in the ass; but we don't have to carry the burden of it's existence throughout our code. There are nullless languages; excellent. I don't currently work in them, so being able to remove the issues and concerns and code decay that comes with null splattering throughout the code is a win when using µObjects.

The discouragement of nulls in µObjects is to never return nulls. This can definitely be applied in many styles of coding. The value here is that a null will only come into the system from an external resource. With µObjects, this resource is encapsulated in a single class. There's no SomeLibrary.GetValue() calls scattered through the system. It's a single µObject that encapsulates the external resource (static or otherwise). Please start doing this in non-µObjects; you'll be doing us all a huge favor. As it is with common code-bases. Libraries and frameworks are spread through our code, with no single point we can prevent a null from getting in. Once a null gets in; it's insidious and corrupts the code. We suddenly have to have null-checks everywhere because WHO KNOWS where a null may come from.

With µObjects, we know. It can come from out BookEnds. We handle it there. Do whatever is appropriate to prevent a null from escaping the BookEnd.

When you do this; the rest of your code; your business rules, your UI, your messages; everything you write - There's no need to check for nulls. No guard clauses around every constructor and public method. You just write your code. Your quick, simple, and beautiful code.

Any question about why there's no protection against null in my objects is met with, "Show me how it could be passed in".
If it can - then I get to patch that hole. Mostly though; there's not a way for the null to get into the system.
In C# I'm using the null-coalescing ?? feature to do some simple caching. I'm taking advantage of a null (and yes, technically this could be argued to be immutable; but I don't consider the cached data to be part of the "state"). By taking advantage of this null; I'm avoiding a lot of extra boiler plate for a value that won't leave the class. I could introduce a Null-Object pattern and check against that...
I hate defending exceptions to rules. It's a crack in the code which can be exploited through malice or ignorance. It needs to be defended. SOOOOO... While attempting to defend it; I came up with a way to prevent it from spreading.
Which is another layer of abstraction. It's a Cache class. I bet there's plenty of examples of these; so I'll write my own.
This class will still probably have the null container; but it's not limited to a single class. It won't infect the system... as easily.

    public class Cache<T> where T : class
        private T _cache;
        public async Task<T> Retrieve(Func<Task<T>> func) => _cache ?? ( _cache = await func() );

Used like the following for caching a network response.

return new Cache<T>().Retrieve(async () => await _response.ContentAsync());

I could remove the null-coalescing though the use of a boolean; but this is smaller. It better fits with Kent Beck's 4 rules of simple design.

Hiding the null aspect like this keeps it out of all other classes. It makes the system ignorant of nulls. While ?? removes the appearance of null in the code; it's still there behind the curtain. With the example Cache class; we've put it in the dungeon. We know it's there, but the guests will never be bothered.

Show Comments