Wednesday 8 November 2017

Null Object Pattern

The null object pattern provides an object that prevents a nullreference exception, but still notifies the user now that the object they're looking for is missing; as per usual let's start with with a person class.

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName { get => $"{FirstName} {LastName}"; }
    public Person(string FirstName, string LastName)
    {
        this.LastName = LastName;
        this.FirstName = FirstName;
    }

}

nothing special just some first and last name properties and full name read-only property. next we'll create a People class.

class People
{
    IEnumerable<Person> _people;
    Person nullPerson = new Person("No ", "Person");

    public People(params Person[] people) => _people = people;

    public Person GetPerson(string Name)
        => _people.FirstOrDefault(p => p.FirstName == Name) ?? nullPerson;

}

this class contains an enumerable of people and let's the user return a person based on their first name. now the interesting part is that if the GetPerson function doesn't find a person with the specified first name, instead of returning null, it returns the nullPerson instance of the Person class.

Now when we take a look at our main class.

class Program
{
    static void Main(string[] args)
    {
        var tomek = new Person("Tomek", "Chooch");
        var marin = new Person("Marin", "Smartzik");

        var people = new People(pawel, tomek, marin);

        Console.WriteLine(people.GetPerson("Tomek").FullName);
        Console.WriteLine(people.GetPerson("Magda").FullName);
    }

}

we can see that even though the person Magda isn't in our list, when we write the FullName property instead of getting a null reference exception we simply write "No Person" to the console. Is this ideal? well as always it just depends there will be times when it does make sense to use this pattern, there will be times where it makes sense to throw the null reference exception and there will be times when it makes sense to get the object and check if it's null then operate on it if it's not null. It just depends on the circumstances.