0% found this document useful (0 votes)
2 views14 pages

2 NullObjectPattern

Uploaded by

davidispl01
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views14 pages

2 NullObjectPattern

Uploaded by

davidispl01
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

CHAPTER 25

Null Object Pattern


This chapter covers the Null Object pattern.

Definition
There is no universally accepted definition. So, let’s choose the definition from
Wikipedia which says the following:

“In object-oriented computer programming, a null object is an object with


no referenced value or with defined neutral (‘null’) behavior. The null object
design pattern describes the uses of such objects and their behavior (or lack
thereof ). It was first published in the Pattern Languages of Program Design
book series.”

Concept
The pattern can implement a “do-nothing” relationship, or it can provide a default
behavior when an application encounters a null object instead of a real object. In simple
words, the core aim is to make a better solution by avoiding a “null objects check” or
“null collaborations check” through if blocks.
To explain the concept better, I will explain the problems associated with the
following program (which is basically a faulty program), analyze the probable solutions,
and, ultimately, implement the concept of this design pattern.

341
© Vaskaran Sarcar 2018
V. Sarcar, Design Patterns in C#, [Link]
Chapter 25 Null Object Pattern

A Faulty Program
Here’s a faulty program:

using System;

namespace NullObjectPattern
{
    interface IVehicle
    {
        void Travel();
    }
    class Bus : IVehicle
    {
        public static int busCount = 0;
        public Bus()
        {
            busCount++;
        }
        public void Travel()
        {
            [Link]("Let us travel with Bus");
        }
    }
    class Train : IVehicle
    {
        public static int trainCount = 0;
        public Train()
        {
            trainCount++;
        }
        public void Travel()
        {
            [Link]("Let us travel with Train");
        }
    }

342
Chapter 25 Null Object Pattern

    class Program
    {
        static void Main(string[] args)
        {
            [Link]("***Null Object Pattern Demo***\n");
            string input = [Link];
            int totalObjects = 0;

            while (true)
            {
                [Link]("Enter your choice(Type 'a' for Bus, 'b'
for Train) ");
                input = [Link]();
                IVehicle vehicle = null;
                switch (input)
                {
                    case "a":
                        vehicle = new Bus();
                        break;
                    case "b":
                        vehicle = new Train();
                        break;                    
                }
                totalObjects = [Link] + [Link];          
                    [Link]();                
                [Link]("Total objects created in the
system ={0}", totalObjects);
                }            
        }
    }   
}

343
Chapter 25 Null Object Pattern

Output with Valid Inputs


Here is some output with valid inputs:

Enter your choice(Type 'a' for Bus, 'b' for Train)


a
Let us travel with Bus
Total objects created in the system =1
Enter your choice(Type 'a' for Bus, 'b' for Train)
b
Let us travel with Train
Total objects created in the system =2
Enter your choice(Type 'a' for Bus, 'b' for Train)
a
Let us travel with Bus
Total objects created in the system =3
Enter your choice(Type 'a' for Bus, 'b' for Train)

Analysis with Unwanted Input


Let’s assume that by mistake the user has supplied a different character, say e, as shown
here:

Enter your choice(Type 'a' for Bus, 'b' for Train)


a
Let us travel with Bus
Total objects created in the system =1
Enter your choice(Type 'a' for Bus, 'b' for Train)
b
Let us travel with Train
Total objects created in the system =2
Enter your choice(Type 'a' for Bus, 'b' for Train)
a
Let us travel with Bus
Total objects created in the system =3
Enter your choice(Type 'a' for Bus, 'b' for Train)
e

344
Chapter 25 Null Object Pattern

Encountered Exception
This time, you will receive the runtime exception [Link], as
shown in Figure 25-1.

Figure 25-1. A runtime exception occurred

Immediate Remedy
The immediate remedy is to do a null check before invoking the operation, as shown
here:

if (vehicle != null)
{
  [Link]();
}

Analysis
This solution will work in this case. But think of an enterprise application. If you need to
do null checks for every possible scenario like this, you have n number of if conditions
to evaluate. That will make your code dirty, and as a side effect, the maintenance
becomes tough. Instead, you can use the Null Object pattern in this kind of scenario.

345
Chapter 25 Null Object Pattern

Real-Life Example
A washing machine can wash properly if the door is closed and there is a smooth water
supply without any internal leakage. But suppose, on one occasion, you forget to close
the door or the water supply stops while it’s running. The washing machine should not
damage itself in those situations, and it should make a beeping sound or create some
alarm to draw your attention to the issue.

Computer World Example


As mentioned earlier, in an enterprise application, you can avoid a large number of null
checks and if/else blocks using this design pattern. The following implementation
gives a nice overview of this pattern.

Illustration
In the code implementation, assume that you have two types of vehicles: Bus and Train.
A client can opt for a bus or a train through different inputs: a or b. If by mistake the
user supplies any invalid data (in other words, any input other than a or b in this case),
the user cannot travel at all. The application will ignore those invalid inputs by doing
nothing through a NullVehicle object. In the following example, you will not create
NullVehicle objects repeatedly; once a NullVehicle object is created, you will simply
reuse that object.

346
Chapter 25 Null Object Pattern

Class Diagram
Figure 25-2 shows the class diagram.

Figure 25-2. Class diagram

347
Chapter 25 Null Object Pattern

Solution Explorer View


Figure 25-3 shows the high-level structure of the parts of the program.

Figure 25-3. Solution Explorer View

348
Chapter 25 Null Object Pattern

Implementation
Here’s the implementation:

using System;
namespace NullObjectPattern
{
    interface IVehicle
    {
        void Travel();
    }
    class Bus : IVehicle
    {
        public static int busCount = 0;
        public Bus()
        {
            busCount++;
        }
        public void Travel()
        {
            [Link]("Let us travel with Bus");
        }
    }
    class Train : IVehicle
    {
        public static int trainCount = 0;
        public Train()
        {
            trainCount++;
        }
        public void Travel()
        {
            [Link]("Let us travel with Train");
        }
    }

349
Chapter 25 Null Object Pattern

    class NullVehicle : IVehicle


    {
        private static readonly NullVehicle instance = new NullVehicle();
        public static int nullVehicleCount = 0;
        public static NullVehicle Instance
        {
            get
            {
                //[Link]("We already have an instance now.
Use it.");
                return instance;
            }
        }
        public void Travel()
        {
            //Do Nothing
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            [Link]("***Null Object Pattern Demo***\n");
            string input = [Link];
            int totalObjects = 0;

            while (input !="exit")


            {
                [Link]("Enter your choice( Type 'a' for Bus, 'b'
for [Link] 'exit' to quit) ");
                input = [Link]();
                IVehicle vehicle = null;
                switch (input)

350
Chapter 25 Null Object Pattern

                {
                    case "a":
                        vehicle = new Bus();
                        break;
                    case "b":
                        vehicle = new Train();
                        break;
                    case "exit":
                        [Link]("Closing the application");
                        vehicle = [Link];
                        break;
                    default:
                        vehicle = [Link];
                        if(input=="exit")
                        {
                            [Link]("Closing the application.
Press Enter at end.");                        
                         }                        
                        break;
                }
                totalObjects = [Link] + [Link]+
[Link];
                //ride the vehicle
                //if (vehicle != null)
                    [Link]();
                //}

                
[Link]("Total objects created in the system ={0}",
totalObjects);

          }
            [Link]();
        }
    }
}

351
Chapter 25 Null Object Pattern

Output
Here’s the output:

***Null Object Pattern Demo***

Enter your choice(Type 'a' for Bus, 'b' for [Link] 'exit' to quit)
a
Let us travel with Bus
Total objects created in the system =1
Enter your choice(Type 'a' for Bus, 'b' for [Link] 'exit' to quit)
b
Let us travel with Train
Total objects created in the system =2
Enter your choice(Type 'a' for Bus, 'b' for [Link] 'exit' to quit)
c
Total objects created in the system =2
Enter your choice(Type 'a' for Bus, 'b' for [Link] 'exit' to quit)
d
Total objects created in the system =2
Enter your choice(Type 'a' for Bus, 'b' for [Link] 'exit' to quit)
e
Total objects created in the system =2
Enter your choice(Type 'a' for Bus, 'b' for [Link] 'exit' to quit)
b
Let us travel with Train
Total objects created in the system =3
Enter your choice(Type 'a' for Bus, 'b' for [Link] 'exit' to quit)
exit
Closing the [Link] Enter at end.
Total objects created in the system =3

352
Chapter 25 Null Object Pattern

Consider the following:

• Invalid inputs and their effects are shown in bold.

• Notice that objects counts are not increasing because of null vehicle
objects/invalid inputs.

• You did not perform any null check. Still the program execution is not
interrupted because of invalid user inputs.

Q&A Session
1. At the beginning of the implementation, I see an additional
object is created. Is this intentional?

Answer:

To save some computer memory/storage, I have followed a


Singleton design pattern mechanism in the architecture of the
NullVehicle class. You do not want to create a NullVehicle
object for each invalid input. Over a period of time, it is likely that
the application may need to deal with a large number of invalid
inputs. If you do not guard against this situation, a huge number
of NullVehicle objects will reside in the system (which is basically
useless), and they will occupy big amount of memory and you
may notice the bad side-effects. (For example, the system may
become slow, applications response time may increase etc.)

2. When should you use this pattern?


Answer:

• The pattern is useful if you do not want to encounter a


NullReferenceException (for example, if by mistake you try to
invoke a method of a null object).

• You can ignore lots of null checks in your code.

• Without these null checks, you make your code cleaner and easily
maintainable.

353
Chapter 25 Null Object Pattern

3. What are the challenges associated with the Null Object


pattern?

Answer:

• Most often, you may want to find and fix the root cause of failure.
So, if you throw a NullReferenceException, that can work better
for you. You can always handle those exceptions in a try/catch
block or in a try/catch/finally block and update the log
information accordingly.

• The Null Object pattern basically helps you to implement a


default behavior when you unconsciously want to deal with an
object that is not present at all. But trying to supply such a default
behavior for all kinds of objects is not appropriate always.

354

You might also like