Kcko
3/18/2020 - 9:08 AM

9. Null Object

<?php

interface Logger
{
    public function log(string $str);
}


class PrintLogger implements Logger
{
    public function log(string $str)
    {
        echo $str;
    }
}


class NullLogger implements Logger
{
    public function log(string $str)
    {
        // do nothing
    }
}


class Service
{
    private Logger $logger;

    public function __construct(Logger $logger)
    {
        $this->logger = $logger;
    }

    /**
     * do something ...
     */
    public function doSomething()
    {
        // notice here that you don't have to check if the logger is set with eg. is_null(), instead just use it
        $this->logger->log('We are in '.__METHOD__);
    }
}

// USAGE:
class LoggerTest extends TestCase
{
    public function testNullObject()
    {
        $service = new Service(new NullLogger());
        $this->expectOutputString('');
        $service->doSomething();
    }

    public function testStandardLogger()
    {
        $service = new Service(new PrintLogger());
        $this->expectOutputString('We are in DesignPatterns\Behavioral\NullObject\Service::doSomething');
        $service->doSomething();
    
<?php

interface Cache
{
    public function has(string $key): bool;

    public function get(string $key);

    public function set(string $key, $data): void;
}


class ArrayCache implements Cache
{
    private $data = [];

    public function get(string $key)
    {
        if ($this->has($key)) {
            return $this->data[$key];
        }
        return false;
    }

    public function set(string $key, $data): void
    {
        $this->data[$key] = $data;
    }

    public function has(string $key): bool
    {
        return array_key_exists($key, $this->data);
    }
}


class DummyCache implements Cache
{
    public function get(string $key)
    {
    }

    public function set(string $key, $data): void
    {
    }

    public function has(string $key): bool
    {
        return false;
    }
}