비용 절감 Null Object 패턴

9948 단어 디자인 패턴PHP

Null Object 패턴의 목적



오브젝트를 요구해 그 결과가 null 인가 어떤가의 판정이 반복해 나타나는 경우에, 그 null 치를 Null Object 로 옮겨놓는 것으로, 판정 처리를 하고 있는 수속적 코드를 제외한다.
if (is_null($user)) {
  $userName = '';
} else {
  $userName = $user->userName();
}

기본 패턴



상속 ver.


인터페이스 ver.


예(상속 ver.)


<?php
class User
{
    private string $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    public function isNull(): bool
    {
        return false;
    }

    public function userName(): string
    {
        return $this->name;
    }

    public static function nullObject(): NullUser
    {
        return new NullUser();
    }
}

class NullUser extends User
{
    public function __construct() {
        parent::__construct('');
    }

    public function isNull(): bool
    {
        return true;
    }
}

function displayUserName(User $user) {
  echo $user->userName();
}

displayUserName(new User('tanaka'));    // 'tanaka'
displayUserName(User::nullObject());  // ''

보충



클라이언트가 User 와 NullUser 로 같은 응답 (이번이라면 userName 의 취득)을 요구하는 경우는 상기와 같이 할 수 있지만, 다른 응답을 요구하는 경우는 여전히 is_null 판정을 실시하게 된다.
// my ページでユーザが取れない場合はエラー
if ($user->isNull()) {
  // エラー処理、エラー画面表示
}

주의점



Null Object 클래스를 클래스 마다 작성하는데 비용이 들기 때문에, 얻을 수 있는 효과를 고려해 도입할지 어떨지의 판단이 필요.

응용 패턴



Null Object 클래스를 준비하지 않고, Null의 경우의 값을 클래스내에 정의하는 것으로 Null Object 패턴을 실현한다.
이것에 의해, Null Object 클래스의 작성 비용을 줄일 수가 있다.


<?php
class User
{
    private const NULL_VALUE = '';
    private string $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    public static function nullObject(): self
    {
        return new self(self::NULL_VALUE);
    }

    public function equal(self $another): bool
    {
      reutrn $this == $another;
    }
}

$user = new User('tanaka');
$nullUser = User::nullObject();
$user->userName();      // 'tanaka'
$nullUser->userName();  // ''

if ($user->equal(User::nullObject())) { // nullObject の判定は equal() で行う
  // 特別処理
}

이름이 하늘이지만 존재하는 유저를 인정하고 싶은 경우는 Null Object 와 구별을 할 수 없기 때문에 이 패턴은 사용할 수 없지만, 실제로는 User 속성에 Id 등이 들어가는 것을 생각하면, 모두 하늘의 유저를 Null Object 와 구별 하고 싶은 케이스는 상정하기 어렵다.
응용 패턴이 부적절한 경우가 나오면 기본 패턴으로 수행하는 것을 고려하십시오.

참고



신규 버전 리팩토링 - 기존 코드를 안전하게 개선
애자일 소프트웨어 개발의 오의 제2판 오브젝트 지향 개발의 신수와 장인의 기술

좋은 웹페이지 즐겨찾기