Factory Methodパターンを実装する場合の注意点

今回の内容はプログラマーにとっては常識な内容かもしれません。完全な僕のうっかりミスでハマってしまったことがあったのでまとめてみました。

Factory Methodパターンとは

まずFactory Methodパターンとは何かと。

Factory Method パターン(ファクトリメソッド・パターン)とは、GoF(Gang of Four; 4人のギャングたち)によって定義されたデザインパターンの1つである。 Factory Method パターンは、オブジェクトの生成をサブクラスに委ねることによって、プログラム内で使用されるインスタンスの型の制約を緩めることを目的とする。

Factory Method パターン – Wikipedia

僕は与えられた引数によって生成するクラスを変えたかったので下記のようなコードを書きました(趣旨だけわかるようにかなり簡素化しています)。

class factory {
  public function __construct( $key ) {
    $className = $key.'Product';
    return new $className();
  }
}
abstract class product {
  public function __construct() {
    〜処理〜
  }
  abstract function read();
}
class carProduct extends product {
  public function move() {
    return '走りましたよ!';
  }
}
// 実行
$factory = new factory( 'car' );
echo $factory->move();

で、「走りましたよ!」と出てほしかったのですが、出たのは「undefined method move〜」というエラー!ハマった!
ここでFactoryクラスにmoveメソッドを加えたらそれが実行される始末。

結局原因は何だったかというと、コンストラクタでインスタンス化したオブジェクトを返そうとしていたところ。コンストラクタって戻り値無いんですよ。

なぜ戻り値が無いのかというと、コンストラクタの戻り値はインスタンスへの参照であり
コンストラクタはインスタンス生成時以外に呼び出されることは無いからです

コンストラクタ

なので、下記のようにFactoryクラスと実行ファイルを修正。

class factory {
  public function __construct() {
  }
  public function getInstance( $key ) {
    $className = $key.'Product';
    return new $className();
  }
}
// 実行
$factory = new factory();
$car = $factory->getInstance( 'car' );
echo $factory->move();

無事、「走りましたよ!」が出力されます。

この記事を書くためにいろいろ調べてて思ったんですが、上記はFactory MethodパターンではなくてFactoryパターン…?まぁ「オブジェクトの生成をサブクラスに委ねる」が成り立ってないし。他にもAbstract Factoryパターンってのもあるみたいですが…???このあたりも勉強が必要ですね…。

MW WP Form

MW WP Form はショートコードベースのフォームプラグインです。多くの機能を持っており、例えば、多くのバリデーションルール、問い合わせデータの保存、そしてグラフ機能集計などを使用することができます。

さらに詳しく
Habakiri

Habakiri

Bootstrap ベースのシンプルな WordPress テーマ。レスポンシブ、多くのカスタマイズ機能。圧縮された CSS・JS を使用する高速化対策。Microformats 対応。Sass、クラスベースの functions.php。

さらに詳しく
basis-stylus

Basis

軽量なレスポンシブ Stylus/CSS フレームワーク。Flexbox ベースのグリッドシステム、疎結合なコンポーネント、バーティカルリズム。

さらに詳しく