mirror of
https://github.com/DesignPatternsPHP/DesignPatternsPHP.git
synced 2025-08-06 23:16:33 +02:00
start a restructure
This commit is contained in:
18
Behavioral/NullObject/LoggerInterface.php
Normal file
18
Behavioral/NullObject/LoggerInterface.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\NullObject;
|
||||
|
||||
/**
|
||||
* LoggerInterface is a contract for logging something
|
||||
*
|
||||
* Key feature: NullLogger MUST inherit from this interface like any other Loggers
|
||||
*/
|
||||
interface LoggerInterface
|
||||
{
|
||||
/**
|
||||
* @param string $str
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function log($str);
|
||||
}
|
21
Behavioral/NullObject/NullLogger.php
Normal file
21
Behavioral/NullObject/NullLogger.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\NullObject;
|
||||
|
||||
/**
|
||||
* Performance concerns : ok there is a call for nothing but we spare an "if is_null"
|
||||
* I didn't run a benchmark but I think it's equivalent.
|
||||
*
|
||||
* Key feature : of course this logger MUST implement the same interface (or abstract)
|
||||
* like the other loggers.
|
||||
*/
|
||||
class NullLogger implements LoggerInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function log($str)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
17
Behavioral/NullObject/PrintLogger.php
Normal file
17
Behavioral/NullObject/PrintLogger.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\NullObject;
|
||||
|
||||
/**
|
||||
* PrintLogger is a logger that prints the log entry to standard output
|
||||
*/
|
||||
class PrintLogger implements LoggerInterface
|
||||
{
|
||||
/**
|
||||
* @param string $str
|
||||
*/
|
||||
public function log($str)
|
||||
{
|
||||
echo $str;
|
||||
}
|
||||
}
|
20
Behavioral/NullObject/README.md
Normal file
20
Behavioral/NullObject/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Null Object
|
||||
|
||||
## Purpose
|
||||
|
||||
NullOutput is a example of NullObject pattern. It is not formally a Design Pattern by the GoF but it's a schema which appears frequently enough to
|
||||
be a pattern. Furthermore it is a really good pattern in my opinion:
|
||||
|
||||
* the code in the client is simple
|
||||
* it reduces the chance of null pointer exception
|
||||
* less "if" => less test cases
|
||||
|
||||
Every time you have a method which returns an object or null, you should return an object or a `NullObject`. With NullObject, you don't need
|
||||
a statement like `if (!is_null($obj)) { $obj->callSomething(); }` anymore.
|
||||
|
||||
## Examples
|
||||
|
||||
* Symfony2: null logger of profiler
|
||||
* Symfony2: null output in Symfony/Console
|
||||
* null handler in a Chain of Responsibilities pattern
|
||||
* null command in a Command pattern
|
34
Behavioral/NullObject/Service.php
Normal file
34
Behavioral/NullObject/Service.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\NullObject;
|
||||
|
||||
/**
|
||||
* Service is dummy service that uses a logger
|
||||
*/
|
||||
class Service
|
||||
{
|
||||
/**
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* we inject the logger in ctor and it is mandatory
|
||||
*
|
||||
* @param LoggerInterface $log
|
||||
*/
|
||||
public function __construct(LoggerInterface $log)
|
||||
{
|
||||
$this->logger = $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* do something ...
|
||||
*/
|
||||
public function doSomething()
|
||||
{
|
||||
// no more check "if (!is_null($this->logger))..." with the NullObject pattern
|
||||
$this->logger->log('We are in ' . __METHOD__);
|
||||
// something to do...
|
||||
}
|
||||
}
|
30
Behavioral/NullObject/Test/LoggerTest.php
Normal file
30
Behavioral/NullObject/Test/LoggerTest.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace DesignPatterns\Tests\NullObject;
|
||||
|
||||
use DesignPatterns\NullObject\NullLogger;
|
||||
use DesignPatterns\NullObject\Service;
|
||||
use DesignPatterns\NullObject\PrintLogger;
|
||||
|
||||
/**
|
||||
* LoggerTest tests for different loggers
|
||||
*/
|
||||
class LoggerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
public function testNullObject()
|
||||
{
|
||||
// one can use a singleton for NullObjet : I don't think it's a good idea
|
||||
// because the purpose behind null object is to "avoid special case".
|
||||
$service = new Service(new NullLogger());
|
||||
$this->expectOutputString(null); // no output
|
||||
$service->doSomething();
|
||||
}
|
||||
|
||||
public function testStandardLogger()
|
||||
{
|
||||
$service = new Service(new PrintLogger());
|
||||
$this->expectOutputString('We are in DesignPatterns\NullObject\Service::doSomething');
|
||||
$service->doSomething();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user