LoginSignup
20
21

More than 5 years have passed since last update.

PHP: イミュータブルなオブジェクトの実装方法

Last updated at Posted at 2019-01-05

本稿ではPHPでイミュータブルなオブジェクトを実装する方法を紹介する。

なお、本稿で実装したサンプルコードはGitHubで公開しているので必要であれば参考にしてほしい。

まずはミュータブル(変更可能)なオブジェクトの実装を見てみよう。

Product.php
final class Product
{
    /**
     * @var int
     */
    private $price;

    public function __construct(int $price)
    {
        $this->price = $price;
    }

    public function getPrice(): int
    {
        return $this->price;
    }

    public function setPrice(int $price): void
    {
        $this->price = $price;
    }
}

このミュータブルなProductクラスでは、setPriceメソッドを呼ぶと$priceプロパティの状態が変更される。

$product = new Product(100);
echo $product->getPrice(); //=> 100

$product->setPrice(300);
echo $product->getPrice(); //=> 300

このsetPriceメソッドのように、呼び出すことでオブジェクトの状態を変更するメソッドのことを「破壊的なメソッド」という。イミュータブル(変更不可)なオブジェクトには、破壊的なメソッドが存在しないという特徴がある。

それでは、ミュータブルなProductクラスをイミュータブルなクラスに作り変えてみよう。

final class Product
{
    // ...

    public function setPrice(int $price): self
    {
        return new self($price);
    }
}

破壊的なメソッドsetPrice$priceプロパティに値を代入するものだったが、イミュータブルなProductクラスのメソッドでは、その代りに新しい$priceを持ったProductクラスを生成して返す実装になる。完成形のコードは次のようになる:

Product.php
final class Product
{
    /**
     * @var int
     */
    private $price;

    public function __construct(int $price)
    {
        $this->price = $price;
    }

    public function getPrice(): int
    {
        return $this->price;
    }

    public function setPrice(int $price): self
    {
        return new self($price);
    }
}

イミュータブルなProductクラスでは、setPriceを実行してももとのインスタンスの状態が変わることがない:

$product1 = new Product(100);
echo $product1->getPrice(); //=> 100

$product2 = $product1->setPrice(300);
echo $product1->getPrice(); //=> 100
echo $product2->getPrice(); //=> 300

続き: PHP: 属性が多いイミュータブルなオブジェクトの実装方法

20
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
21