3.7. Null Object
3.7.1. Zweck
NullObject ist keines der Gang-Of-Four Design Patterns aber ein Muster, dass immer wieder häufig auftritt und deswegen erwähnt werden sollte. Es hat folgende Vorzüge:
Client Code wird vereinfacht
Verringert die Möglichkeit einer Nullpoint-Exception
Weniger Ausnahmefälle bedingen weniger Testfälle
Methoden, die ein Objekt oder Null zurückgeben, sollten stattdessen ein Objekt oder NullObject
zurückgeben. NullObject``s vereinfachen Boilerplate-code wie z.B. ``if (!is_null($obj)) { $obj->callSomething(); }
zu $obj->callSomething();
, indem sie die konditionale Prüfung im Clientcode entfernen.
3.7.2. Beispiele
Null Logger oder Null Output um einen Standardweg einzuhalten, über den Objekte miteinander interagieren auch wenn Objekte nichts tun sollen
Nullhandler in einem Chain Of Responsibilities Pattern
Null Command in einem Command-Pattern
3.7.3. UML-Diagramm

3.7.4. Code
Du findest den Code hierzu auf GitHub
Service.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\NullObject;
6
7class Service
8{
9 public function __construct(private Logger $logger)
10 {
11 }
12
13 /**
14 * do something ...
15 */
16 public function doSomething()
17 {
18 // notice here that you don't have to check if the logger is set with eg. is_null(), instead just use it
19 $this->logger->log('We are in ' . __METHOD__);
20 }
21}
Logger.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\NullObject;
6
7/**
8 * Key feature: NullLogger must inherit from this interface like any other loggers
9 */
10interface Logger
11{
12 public function log(string $str);
13}
PrintLogger.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\NullObject;
6
7class PrintLogger implements Logger
8{
9 public function log(string $str)
10 {
11 echo $str;
12 }
13}
NullLogger.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\NullObject;
6
7class NullLogger implements Logger
8{
9 public function log(string $str)
10 {
11 // do nothing
12 }
13}
3.7.5. Test
Tests/LoggerTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\NullObject\Tests;
6
7use DesignPatterns\Behavioral\NullObject\NullLogger;
8use DesignPatterns\Behavioral\NullObject\PrintLogger;
9use DesignPatterns\Behavioral\NullObject\Service;
10use PHPUnit\Framework\TestCase;
11
12class LoggerTest extends TestCase
13{
14 public function testNullObject()
15 {
16 $service = new Service(new NullLogger());
17 $this->expectOutputString('');
18 $service->doSomething();
19 }
20
21 public function testStandardLogger()
22 {
23 $service = new Service(new PrintLogger());
24 $this->expectOutputString('We are in DesignPatterns\Behavioral\NullObject\Service::doSomething');
25 $service->doSomething();
26 }
27}