4
1

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 5 years have passed since last update.

ReluxAdvent Calendar 2018

Day 10

Immutable classes and propertiesについて

Posted at

こんにちは。

LocoPartnersでReluxのサーバーサイドを担当している山口です。
この記事は「Relux Advent Calendar 2018」10日目の記事です。

本日はphp rfcで議論中になっているものから、個人的に取り込まれると楽しそうだなと感じている Immutable classes and properties という提案について紹介を行っていきたいと思います。

紹介と言っても元ページの内容を書いてるだけですが、php rfc自体に今まで興味がなかった人が興味を示すキッカケとなってくれると幸いです。また、議論中のものなので 最終的にどういった形で取り込まれるのかそもそも取り込まれるのか は誰にも解りません。


Immutable classes and properties

php自体にImmutableなClassとPropertyを設定可能な機能を導入してみませんかという提案です。現時点(2018/12/10)で提案されている例は下記になります。

Immutable Class

immutable class Email {
  public $email;
 
  public function __construct ($email) {
    $this->email = $email;
  }
}
 
$email = new Email("foo@php.net");
$email->email = "bar@php.net" // Call will result in Fatal Error
immutable class Foo{}
class Bar extends Foo{} // Will result in Fatal Error

Immutable Classを用いるとClassのPropertyはImmutableとして暗黙的に設定されます。これによりgetterなどで取得する必要のあるPropertyを安心して public として ImmutableClass->attribute などで値を取得することが出来そうですね。

もう、getEmail()といったgetter用のfunctionを用意したりする手間や、どこかで値が変わることに心配する必要も無くなるのでしょうね、

また、継承を行う際は継承を行う子クラスもImmutable Classである必要があることや、参照を利用した値の変更も不可となっています。

Immutable Properties

class User {
  private $id;
  public immutable $email;
 
  public function __construct ($id, $email) {
    $this->id = $id;
    $this->email = $email;
  }
}
immutable class Email{}
 
class User {
  public immutable $email;
 
  public function __construct (Email $email) {
    $this->email = $email;
  }
}

Classの一部のPropertyにImmutable Propertyを用いることも可能です。
しかし、下記のように幾つかの制約があります。

  • Immutable Propertyにオブジェクトが代入される場合、代入するObjectもImmutableである必要があること。
  • Immutable PropertyにResource(ファイル等)であるものは割り当てることはできないこと。
  • Immutable Propertyに配列は割り当てることができないこと。
  • 子クラスで親クラスのImmutable Propertyをoverrideする場合は子クラスでもImmutable Propertyとして宣言する必要があること

比較

immutable class Email {
  public $email;
 
  public function __construct ($email) {
    // validation
 
    $this->email = $email;
  }
}
 
$email1 = new Email("foo@php.net");
$email2 = new Email("foo@php.net");
var_dump($email1 === $email2); // bool(true)

ImmutableなObjectの場合には通常のObjectとは異なり、型とその中に設定されているプロパティの値が同じである場合は同一としてみなされます。

MoneyPatternの実装例

元ページには、この他にMoneyPatternと呼ばれるものを用いてのImmutable Classを用いた場合と用いない場合での具体例な実装例が記載されています。興味がある方はそちらも是非ご覧になってください。

さいごに

現時点でも、開発者側で独自に実装をすることでImmutableなClassやPropertyを実装することは可能ですが、統一された方法が言語として用意されimmutableと付与されていればImmutableであることを保障してくれるのが嬉しいですね。

それでは、明日も引き続きRelux Advent Calendar 2018をお楽しみください。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?