typesafeな定数
typesafeな定数については、型に安全な定数あたりを参照。Java5以前だと
public final class Card { private String name; public static final Card CLUBS = new Card('clubs'); public static final Card DIAMONDS = new Card('diamonds'); public static final Card HEARTS = new Card('hearts'); public static final Card SPADES = new Card('spades'); private Card(String name) { this.name = name; } public function toString() { return this.name; } }
な感じのコードでtypesafeな定数を実現できます。
以前からずっと「PHPでtypesafeな定数を簡単に書けないか」と思っていたのですが、PHPだと定数(const、define)にオブジェクトを入れること自体が不可能なので、Javaのようなコードで実現するのはムリです。
そこで、定数を返す静的メソッドを用意することで、これに近いことが(一応)できるので晒しておきます。
<?php class Card { private $name; private function __construct($name) { $this->name = $name; } public static function __callStatic($name, $args) { static $objects = null; if (is_null($objects)) { echo "create\n"; $objects = array(); $objects['CLUBS'] = new Card('clubs'); $objects['DIAMONDS'] = new Card('diamonds'); $objects['HEARTS'] = new Card('hearts'); $objects['SPADES'] = new Card('spades'); } if (isset($objects[$name])) { return $objects[$name]; } throw new BadMethodCallException('method not exist'); } public function __toString() { return $this->name; } }
__callStaticを使っているのは、使う側で
Card::CLUBS()
としたいのと、定数ごとのメソッドを用意したくないのが理由です。
実際の使い方は次のような感じ。
<?php function deal(Card $card) { echo $card . "\n"; } deal(Card::CLUBS()); deal(Card::DIAMONDS()); deal(Card::HEARTS()); deal(Card::SPADES()); // エラー // deal(new stdClass());