Null object pattern: Difference between revisions

Content deleted Content added
Citation bot (talk | contribs)
m Removed parameters. | You can use this bot yourself. Report bugs here. | Activated by User:Neko-chan | Category:Software design patterns | via #UCB_Category
m Task 70: Update syntaxhighlight tags - remove use of deprecated <source> tags
Line 106:
==Alternatives==
From C# 6.0 it is possible to use the "?." operator (aka [[Safe_navigation_operator#C.23|null-conditional operator]]), which will simply evaluate to null if its left operand is null.
<sourcesyntaxhighlight lang="csharp">
// compile as Console Application, requires C# 6.0 or higher
using System;
Line 124:
// The output will be:
// 4
</syntaxhighlight>
</source>
 
===Extension methods and Null coalescing===
In some [[Microsoft .NET]] languages, [[Extension method]]s can be used to perform what is called 'null coalescing'. This is because extension methods can be called on null values as if it concerns an 'instance method invocation' while in fact extension methods are static. Extension methods can be made to check for null values, thereby freeing code that uses them from ever having to do so. Note that the example below uses the [[C Sharp (programming language)|C#]] [[Null coalescing operator]] to guarantee error free invocation, where it could also have used a more mundane if...then...else. The following example only works when you do not care the existence of null, or you treat null and empty string the same. The assumption may not hold in other applications.
 
<sourcesyntaxhighlight lang="csharp">
// compile as Console Application, requires C# 3.0 or higher
using System;
Line 151:
// The output will be:
// 18
</syntaxhighlight>
</source>
 
==In various languages==
Line 161:
A language with statically typed references to objects illustrates how the null object becomes a more complicated pattern:
 
<sourcesyntaxhighlight lang="cpp">
#include <iostream>
 
Line 180:
virtual void MakeSound() const override {}
};
</syntaxhighlight>
</source>
 
Here, the idea is that there are situations where a pointer or reference to an <code>Animal</code> object is required, but there is no appropriate object available. A null reference is impossible in standard-conforming C++. A null <code>Animal*</code> pointer is possible, and could be useful as a place-holder, but may not be used for direct dispatch: <code>a->MakeSound()</code> is undefined behavior if <code>a</code> is a null pointer.
Line 190:
Note, that NOT having a null class at all is an important feature, in contrast to languages where "anything is a reference" (e.g. Java and C#). In C++, the design of a function or method may explicitly state whether null is allowed or not.
 
<sourcesyntaxhighlight lang="cpp">
// Function which requires an |Animal| instance, and will not accept null.
void DoSomething(const Animal& animal) {
Line 200:
// |animal| may be null.
}
</syntaxhighlight>
</source>
 
===C#===
Line 206:
C# is a language in which the null object pattern can be properly implemented. This example shows animal objects that display sounds and a NullAnimal instance used in place of the C# null keyword. The null object provides consistent behaviour and prevents a runtime null reference exception that would occur if the C# null keyword were used instead.
 
<sourcesyntaxhighlight lang="csharp">
/* Null object pattern implementation:
*/
Line 260:
unknown.MakeSound(); // outputs nothing, but does not throw a runtime exception
}
}</sourcesyntaxhighlight>
 
===Smalltalk===
Line 280:
 
In Common Lisp, the object <code>nil</code> is the one and only instance of the special class <code>null</code>. What this means is that a method can be specialized to the <code>null</code> class, thereby implementing the null design pattern. Which is to say, it is essentially built into the object system:
<sourcesyntaxhighlight lang="lisp">
;; empty dog class
 
Line 294:
;; innocuous empty body: nil makes no sound.
(defmethod make-sound ((obj null)))
</syntaxhighlight>
</source>
The class <code>null</code> is a subclass of the <code>symbol</code> class, because <code>nil</code> is a symbol.
Since <code>nil</code> also represents the empty list, <code>null</code> is a subclass of the <code>list</code> class, too. Methods parameters specialized to <code>symbol</code> or <code>list</code> will thus take a <code>nil</code> argument. Of course, a <code>null</code> specialization can still be defined which is a more specific match for <code>nil</code>.
Line 305:
 
In [[Duck typing|duck-typed]] languages like [[Ruby (programming language)|Ruby]], language inheritance is not necessary to provide expected behavior.
<sourcesyntaxhighlight lang="ruby">
class Dog
def sound
Line 324:
get_animal.sound
=> nil
</syntaxhighlight>
</source>
Attempts to directly [[Monkey patch|monkey-patch]] NilClass instead of providing explicit implementations give more unexpected side effects than benefits.
 
=== JavaScript ===
In [[Duck typing|duck-typed]] languages like [[JavaScript]], language inheritance is not necessary to provide expected behavior.
<sourcesyntaxhighlight lang="javascript">
class Dog {
sound() {
Line 348:
['dog', null].map((animal) => getAnimal(animal).sound());
// Returns ["bark", null]
</syntaxhighlight>
</source>
 
===Java===
 
<sourcesyntaxhighlight lang="java">
public interface Animal {
void makeSound() ;
Line 368:
}
}
</syntaxhighlight>
</source>
 
This code illustrates a variation of the C++ example, above, using the Java language. As with C++, a null class can be instantiated in situations where a reference to an <code>Animal</code> object is required, but there is no appropriate object available. A null <code>Animal</code> object is possible (<code>Animal myAnimal = null;</code>) and could be useful as a place-holder, but may not be used for calling a method. In this example, <code>myAnimal.makeSound();</code> will throw a NullPointerException. Therefore, additional code may be necessary to test for null objects.
Line 375:
 
=== PHP ===
<sourcesyntaxhighlight lang="php">
interface Animal
{
Line 418:
}
$animal->makeSound(); // ..the null animal makes no sound
</syntaxhighlight>
</source>
 
=== Visual Basic .NET ===
The following null object pattern implementation demonstrates the concrete class providing its corresponding null object in a static field <code>Empty</code>. This approach is frequently used in the .NET Framework (<code>String.Empty</code>, <code>EventArgs.Empty</code>, <code>Guid.Empty</code>, etc.).
 
<sourcesyntaxhighlight lang="vb">
Public Class Animal
Public Shared ReadOnly Empty As Animal = New AnimalEmpty()
Line 439:
End Sub
End Class
</syntaxhighlight>
</source>
 
==Criticism==