Is the use of null an anti-pattern?

In summary, there are programmers who do not believe in null and argue that it is a tool that is misused and causes issues with objects and their relationships. They suggest using inheritance and proper design to enforce object rules rather than relying on null. However, others argue that null is a necessary tool and can be used effectively in certain situations. It ultimately depends on the programmer's preference and the language they are using.
  • #1
SlurrerOfSpeech
141
11
I remember a while back someone told me that there exist programmers who don't believe in null. I thought that was a crazy idea. Until recently, as I've gotten better at OOP and have figure out that if my object has a property that is allowed to be set to null, it usually means that I am not OOPing correctly.

Example:

Let's say I have an object like

Code:
public class JobTracker
{
    public DateTime Started { get; set; }

    public JobStatus Status { get; set; }

    public DateTime? Ended { get; set; }

    public string ErrorMessage { get; set; }
}

I would argue that this is bad design. Someone using the object will have to write code such as

Code:
if (tracker.Status == Status.Failed)
{
     Console.WriteLine(tracker.ErrorMessage);
}

In other words, someone using it has to know or assume rules like

  • Status is Failed => There is error message and end date
  • Status is Succeeded => There is no error message; there is end date
  • Status is InProgress => There is no error message or end date
  • There is end date => Status is Succeeded or Failed
  • There is no end date => Status is InProgress and there is no error message
  • Etcetera
and write code according to those rules. It would be better to design to have the object enforce it's own rules and use inheritance wherever it makes sense to.

Code:
public interface IJobTracker
{
     DateTime Started { get; }

     JobStatus Status { get; }
}

public interface IFinishedJob : IJobTracker
{
      DateTime Ended { get; }
}

public interface IFailedJob : IFinishedJob
{
      string ErrorMessage { get; }
}

This leads to more elegant and failproof code like

Code:
if (tracker is IFailedJob)
{
     Console.WriteLine((tracker as IFailedJob).ErrorMessage);
}

As always, there are tradeoffs. The way I should is not micro-optimal because the runtime environment has to navigate the inheritance chain.

Do you agree with most of what I wrote above? Why or why not?
 
Technology news on Phys.org
  • #2
The best example I can think of are with strings where you might use “” for an empty string vs using null.

Testing the string length will fail when it’s null but not when you use “”.

This might come as you read in data and empty strings populate fields but sometimes you’d place a null there.

This means that string testing would check for non null and then string length before deciding if you have a null string.
 
  • #3
jedishrfu said:
The best example I can think of are with strings where you might use “” for an empty string vs using null.

Testing the string length will fail when it’s null but not when you use “”.

That shouldn't happen unless you reference a variable that isn't initialized already, and even then the compiler should allocate a memory location for the variable. A null string will return a length of 0 and not error out. At least this happens in all versions of VB I've used, as well as FreeBASIC. I'm not 100% sure about C/C++, though, but I would assume similar.
 
  • #4
I've been a professional programmer for more than a decade, we use null all the time. There are some languages that don't have null, so maybe those are the type of people you are referring to that don't believe in null, but for a language like C++, null is something we use and use extensively. You are looking at what null is used for incorrectly. NULL is not really used to define the lack of a value, it's used to define the lack of a RELATIONSHIP. If you are using a string and checking whether or not it is null, you are right in saying that this is not using OOP correctly.For example: how would a linked list work without the possibility of a null pointer? You could certainly point the end of the list to some special instance of a list object, but why?
Code:
inline bool isLeaf() const { return m_nextNodePtr != null; }
Null is a tool, it has it's a very useful one. In your example above, yes, I would not allow any of those fields to be nullable, but those are small objects and they don't have an relationships. Consider an object like this:

Code:
public class Material {
    public Bitmap * albedo;
    public Color albedoTint;
    public Bitmap * normalMap;
    public Bitmap * elevationMap;
    public Bitmap * secondaryNormalMap;
    public TilingParams tiling;
    public PhysicsMaterial * physics;
}

You don't really want to have to go through the process of making sure that your classes all have a perfect isNull() function as well as doing copy-on-write in the database. Most of the time you'll only have a handful of those values filled. You probably wouldn't use normalMap and elevationMap at the same time.
elusiveshame said:
That shouldn't happen unless you reference a variable that isn't initialized already, and even then the compiler should allocate a memory location for the variable. A null string will return a length of 0 and not error out. At least this happens in all versions of VB I've used, as well as FreeBASIC. I'm not 100% sure about C/C++, though, but I would assume similar.
Very wrong assumption. C/C++ does exactly what you tell it to.

Code:
struct myObj {
     std::string * someString;
};

int main(int, char**){
     myObj a;
     std::cout << a -> someString << std::endl;  //Will segfault
}
 
  • #5
Ultimately, an object is a pointer (like in C), and sometimes, it is helpful to be able to designate that this variable, which can contain an address pointing into memory, really does not point anywhere right now.

In either Java or C#, when you are explicitly trying to do garbage collection (such as, when performance matters and you thus must NOT use up all the available memory and have the built-in garbage collector run--because that stops the thread completely!), you want to be able to set objects to null after releasing their resources. This helps signal to the run-time engine that there really is no reason to garbage collect this object in the future.

An example of when you want to do this, very carefully, is when you are doing graphics manipulations. After using, say, a bitmap object to transform something, you really want to release it fully.

There is a time and place for everything, IMO, even null.
 

Related to Is the use of null an anti-pattern?

1. What is the meaning of "null" in programming?

In programming, "null" is a special value that represents the absence of a meaningful value. In other words, it is used to indicate that a variable or object does not currently have a value assigned to it.

2. Is the use of null considered bad practice?

The use of null is often considered an anti-pattern, meaning it is a common practice that is generally discouraged as it can lead to errors and make code more difficult to maintain. It is often better to use alternative approaches, such as using default values or handling exceptions.

3. How does the use of null impact code readability?

The use of null can make code more difficult to read and understand, as it adds an extra layer of complexity and uncertainty. It can also lead to bugs and errors, as it requires careful handling to avoid unexpected behaviors.

4. Are there any situations where the use of null is acceptable?

In some cases, the use of null may be necessary or appropriate, such as when working with legacy code or when dealing with external data sources that may have null values. However, it is important to carefully consider alternative approaches and handle null values in a way that minimizes potential issues.

5. What are some alternatives to using null?

There are several alternatives to using null, such as using default values, using optionals (in languages like Swift and Kotlin), or using exceptions to handle unexpected or missing values. These approaches can help improve code readability and reduce the likelihood of errors caused by null values.

Similar threads

  • Programming and Computer Science
Replies
3
Views
2K
  • Programming and Computer Science
Replies
5
Views
1K
  • Programming and Computer Science
Replies
5
Views
938
  • Programming and Computer Science
Replies
19
Views
1K
Replies
16
Views
2K
  • Programming and Computer Science
Replies
3
Views
945
  • Programming and Computer Science
Replies
2
Views
2K
  • Programming and Computer Science
3
Replies
75
Views
4K
  • Programming and Computer Science
Replies
8
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
5K
Back
Top