PHP設計模式之空物件模式(Null Object)程式碼範例大全(26)

2020-09-19 12:04:23

目的

空物件模式不屬於 GoF 設計模式,但是它作為一種經常出現的套路足以被視為設計模式。它具有如下優點:

  • 使用者端程式碼簡單

  • 可以減少報空指標異常的機率

  • 測試用例不需要考慮太多條件

返回一個物件或 null 應該用返回物件或者 NullObject 代替。NullObject 簡化了死板的程式碼,消除了使用者端程式碼中的條件檢查,例如 if (!is_null($obj)) { $obj->callSomething(); } 只需 $obj->callSomething(); 就行。

例子

  • Symfony2: 空紀錄檔

  • Symfony2: Symfony/Console 空輸出

  • 命令列模式中的空命令

  • 責任鏈模式中的空處理器

UML圖

★官方PHP高階學習交流社群「點選」管理整理了一些資料,BAT等一線大廠進階知識體系備好(相關學習資料以及筆面試題)以及不限於:分散式架構、高可延伸、高效能、高並行、伺服器效能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell指令碼、Docker、微服務、Nginx等多個知識點高階進階乾貨

程式碼

  • Service.php

<?php

namespace DesignPatterns\Behavioral\NullObject;

/**
 * 建立服務類 Service 。
 */
class Service
{
    /**
     * @var LoggerInterface
     * 定義日記類物件。
     */
    private $logger;

    /**
     * @param LoggerInterface $logger
     * 傳入日記類物件引數。
     */
    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    /**
     * 做些什麼。。。
     * 在日記中返回了 '我們在 Service: doSomething 裡' 。
     */
    public function doSomething()
    {
        // 提示:這裡你只是使用它,而不需要通過如:is_null() 檢查 $logger 是否已經設定。
        $this->logger->log('We are in '.__METHOD__);
    }
}
  • LoggerInterface.php

<?php

namespace DesignPatterns\Behavioral\NullObject;

/**
 * 重要特徵:空日記必須像其他日記意向從這個介面繼承。
 */
interface LoggerInterface
{
    public function log(string $str);
}
  • PrintLogger.php

<?php

namespace DesignPatterns\Behavioral\NullObject;

/**
 * 建立一個日記列印類實現日記介面。
 */
class PrintLogger implements LoggerInterface
{
    public function log(string $str)
    {
        echo $str;
    }
}
  • NullLogger.php

<?php

namespace DesignPatterns\Behavioral\NullObject;

/**
 * 建立一個空日記類實現日記介面。
 */
class NullLogger implements LoggerInterface
{
    public function log(string $str)
    {
        // 什麼也不用做
    }
}

測試

  • Tests/LoggerTest.php

<?php

namespace DesignPatterns\Behavioral\NullObject\Tests;

use DesignPatterns\Behavioral\NullObject\NullLogger;
use DesignPatterns\Behavioral\NullObject\PrintLogger;
use DesignPatterns\Behavioral\NullObject\Service;
use PHPUnit\Framework\TestCase;

/**
 * 建立測試單元 LoggerTest 。
 */
class LoggerTest extends TestCase
{
    /**
     * 測試 NullLogger 物件,聯絡上文可以知道什麼也沒做。
     */
    public function testNullObject()
    {
        $service = new Service(new NullLogger());
        $this->expectOutputString('');
        $service->doSomething();
    }

    /**
     * 測試 PrintLogger 物件,聯絡上文可以知道在日記中寫入了 DesignPatterns\Behavioral\NullObject\Service::doSomething 。
     */
    public function testStandardLogger()
    {
        $service = new Service(new PrintLogger());
        $this->expectOutputString('We are in DesignPatterns\Behavioral\NullObject\Service::doSomething');
        $service->doSomething();
    }
}

PHP 網際網路架構師成長之路*「設計模式」終極指南

PHP 網際網路架構師 50K 成長指南+行業問題解決總綱(持續更新)

面試10家公司,收穫9個offer,2020年PHP 面試問題

★如果喜歡我的文章,想與更多資深開發者一起交流學習的話,獲取更多大廠面試相關技術諮詢和指導,歡迎加入我們的群啊,暗號:phpzh(君羊號碼856460874)。

2020年最新PHP進階教學,全系列!

內容不錯的話希望大家支援鼓勵下點個贊/喜歡,歡迎一起來交流;另外如果有什麼問題 建議 想看的內容可以在評論提出