1

I've been reading that the null object pattern will help you to avoid the null checks and null pointer exceptions making your code cleaner to understand.

I have never used it and I find it interesting. "null" won't occupy memory but if I start to replace my null checks with the creation of "default" objects, will this procedure have a negative impact in memory in long term?

ex:

Null Object Pattern

public void DoSomething()
{
  User user = this.GetUser(id);
  string strDisplayName = user.DisplayName;
}

public User GetUser(int id)
{
   User user = this.LoadUserFromDB(id);
   if(user ==  null)
      return User.CreateNull();
   return user;
}

So, as soon as I go out from the scope of the method, the object will be collected by the GC later. But what if I pass through a loop before going out from scope.

public void DoSomething()
{
  users = this.GetAllUsers();
  foreach(User user in users)
  {
     string strAddress = user.Address.StreetName;
     //continue tasks
  }
}

Meanwhile in other class

public Class User
{
   public Address Address
   {
      get
      {
         if(this.Address == null)
            this.Address = Address.CreateNull();
         return this.Address;
      }
   }
}

public class Address
{
   private string streetName;

   public virtual string StreetName
   {
      get { return this.streetName; }
      set { this.streetName = value; }
   }

   public static CreateNull()
   {
      return new NullAddress();
   }
}

public class NullAddress : Address
{
   public override string StreetName
   {
      get { retun String.Empty; }
   }
}

Null check

User user = this.GetUser(id);
string strDisplayName = String.Empty;
if(user != null)
{
   strDisplayName = user.DisplayName;
}

Just check if user is not null, so assign the property value. I won't create a "null" object

Thanks in advance.

2
  • 2
    Maybe just preference but In case of database entities I'd think about using Optional<User> instead of "fake" users because Optional retains the meaning of "no user found". Real null-objects work only well in cases where it's not leading to confusion between proper objects and the null replacement (cf. Liskov substitution principle). Like empty Lists instead of null. Or implementations that just consume input like a logger. Commented Dec 1, 2015 at 21:17
  • Outside of the memory issue where Jon says that the objects should be shared, I'm not sure coding upstream code to avoid breaking downstream code is the way you want to go. Properly written/tested code will expose the issues and then you can solve the root problems. Personally unless User and Address are Structs (which patterns say to use something like User.Empty), I'd let the errors propagate and expose them with well written unit tests. Commented Dec 1, 2015 at 21:25

2 Answers 2

7

Typically null objects aren't created on demand - instead, they're shared. They're typically immutable implementations of some other abstraction (with no-op methods or whatever is suitable) - so they can be shared very easily.

At that point, you've got a single object per null object type you're interested in, over the course of the whole application lifetime - and that's almost certainly insignificant.

Sign up to request clarification or add additional context in comments.

Comments

1

As a pattern null object should be flat and slim, so the answer will be no most of the time. But you should be wary of of null object which support serialization by contract and can cause duplication all over the place.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.