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.
Optional<User>instead of "fake" users becauseOptionalretains 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 emptyLists instead ofnull. Or implementations that just consume input like a logger.UserandAddressareStructs(which patterns say to use something likeUser.Empty), I'd let the errors propagate and expose them with well written unit tests.