1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【PHP】イミュータブルな実装って何が美味しいの?

Last updated at Posted at 2022-12-31

はじめに

保守的性の高いコードの書き方を調べているとイミュータブルなオブジェクトに関する話題を見つけました。

調べてみる

(そもそも)ミュータブルとは

  • mutableは、可変という意味
  • インスタンス(オブジェクト)の状態を変更できるインスタンス(オブジェクト)
  • 想定していない更新が起こる可能性があるためイミュータブルより安全性が低い

(本題の)イミュータブルとは

  • immutableは、不変という意味
  • インスタンス(オブジェクト)の状態を変更できないインスタンス(オブジェクト)
  • 変数に対して再代入をすることができないため、想定していない更新を防ぐことができる。ミュータブルより安全度が高い

書いてみる

Sale.php
class Sales {
    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;
    }
}

$payment1 = new Sales(100);
echo $payment1->getPrice(); // 100
$payment2 = $payment1->setPrice(200);
echo $payment1->getPrice(); // 200

$payment2への代入で$payment1の値が書き換わっていることが分かる。setPriceメソッドのようにオブジェクトの状態を変更できるメソッドのことを「破壊的なメソッド」という。

イミュータブルなオブジェクトの実装では、この破壊的なメソッドによる代入を防ぐため、
セッターで値を入れる際は、新しいインスタンスを作成する。↓

Sales2.php
class Sales2{
    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);
    }
}

$payment1 = new Sales2(100);
echo $payment1->getPrice(); // 100
$payment2 = $payment1->setPrice(200);
echo $payment1->getPrice(); // 100

$payment2への代入で$payment1の値が書き換わらなくなった。
これで意図しない代入により途中で値が書き換わっていることを恐れずに済む。

1
0
2

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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?