3.7. Objeto Nulo (Null Object)
3.7.1. Objetivo
Objeto Nulo (Null Object) não é um padrão de projeto GoF, mas um esquema o qual aparece com frequencia suficiente para ser considerado um padrão. Ele tem os seguintes benefícios:
Código do cliente é simplificado
Reduz a chance de exceções de ponto nulo (null pointer exceptions)
Menores condicionais requerem menos casos de teste
Métodos que retornam um objeto ou nulo devem ao invés disso, retornar um objeto ou NullObject
. NullObject
é simplesmente código boilerplate como if (!is_null($obj)) { $obj->callSomething(); }
para apenas $obj->callSomething();
eliminando então a checagem condicional no código cliente.
3.7.2. Exemplos
Log nulo ou saída nula para preservar uma forma padrão de interação entre objetos, mesmo que não devam fazer nada
manipulador nulo em um padrão de Cadeia de Responsabilidades (Chain of Responsibilities)
commando nulo em um padrão Comando (Command)
3.7.3. Diagrama UML
3.7.4. Código
Você também pode encontrar este código no 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. Teste
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}