【PHPデザインパターン】04_Factory Method~生成処理と使用処理を分離する
引用記事
この記事を書くきっかけになったブログです。
記事内の解説やソースコードは、こちらのブログと著者の公開リポジトリを参考にしています。
Do You PHP はてな〜[doyouphp][phpdp]PHPによるデザインパターン入門 - Factory Method~生成処理と使用処理を分離する
概要
- オブジェクトを生成するときのインターフェイスだけを規定して、実際にどのクラスをインスタンス化するかはサブクラスが決めるようにする。
- 過程は違うが結果は同じ。つまり、生成されるインスタンスはどのクラスのものであれ、同様の「機能」を持っている。
- インスタンス生成用のクラスが存在することから、
Virtual Constructor(仮想的なコンストラクタ)
とも呼ばれている。
-
Template Methodパターン
の代表的な適用例である。
構成要素
Productクラス
- オブジェクト生成メソッド(工場)で生成されるオブジェクト(製品)のAPIを定義するクラス。
- オブジェクト生成メソッドは、
factory method
とも呼ばれる。
ConcreteProductクラス
- Productクラスのサブクラス
- 上記APIのメソッドを実装する。
Creatorクラス
- オブジェクト生成メソッドを提供するクラス。
- このメソッドは、Product型のオブジェクトを返す。クライアントの窓口。
- また、あるConcreteProductオブジェクトを返すために、デフォルトの実装がなされる場合もある。
ConcreteCreatorクラス
- Creatorクラスを継承したサブクラス。
実演
処理の流れ
- 渡した変数の型(配列か文字列か)でオブジェクトのクラスを分ける。表示方法は同じ。
-
MyReaderFactoryクラス
はオブジェクト生成のメソッドを提供する。クライアントとの接点。(Creatorクラス)
- クライアント側(
my_client.php
)から上記のオブジェクトを生成する。
-
MyReaderクラス
でオブジェクト生成に必要な枠(API)を提供する。(Productクラス)
-
ArrayReaderクラス
とStringReaderクラス
でMyReaderクラスに決められた枠を実装し、それぞれのオブジェクトを生成する。(ConcreteProductクラス)
- 今回はConcreteCreatorクラスに該当するクラスはなし。
ファイル構造
MyFactoryMethod
├── MyConcreteProduct
│ ├── ArrayReader.php
│ └── StringReader.php
├── MyReader.php
├── MyReaderFactory.php
└── my_client.php
ソースコード
my_client.php
my_client.php
<?php
namespace DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod;
require dirname(dirname(__DIR__)).'/vendor/autoload.php';
use DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyReaderFactory;
// 型の違う3つのデータを用意する
$array_data = array('apple', 'orange', 'peach', 'banana');
$string_data = 'fruits';
$int_data = 123;
// 変数の内容を表示させる
function show($data)
{
// 結果としてMyReaderクラスのインスタンスが生成される
// 型別のインスタンスが返される
$factory = new MyReaderFactory();
$data = $factory->create($data);
// 型を表示する
$data->display_type();
// 変数の内容を表示する
$data->display_data();
}
// 型別に実行する
show($array_data);
show($string_data);
show($int_data);
MyReaderFactory.php
MyReaderFactory.php
<?php
namespace DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod;
use DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyReader;
use DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyConcreteProduct\ArrayReader;
use DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyConcreteProduct\StringReader;
// MyReaderクラスのインスタンス生成を行うクラス
class MyReaderFactory
{
// MyReaderクラスのインスタンスを生成する
public function create($data)
{
$reader = $this->createReader($data);
return $reader;
}
// 変数の型からMyReaderクラスのサブクラスを判定する
// 変数の型にあったインスタンスを生成する
private function createReader($data)
{
if (is_array($data)) {
return new ArrayReader($data);
} elseif (is_string($data)) {
return new StringReader($data);
} else {
die(gettype($data).'型はサポートしていません');
}
}
}
MyReader.php
MyReader.php
<?php
namespace DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod;
// 読み込み機能を表すインターフェイス
// メソッドはサブクラスで実装される
interface MyReader
{
// 型を表示する
public function display_type();
// 変数の内容を表示する
public function display_data();
}
ArrayReader.php
ArrayReader.php
<?php
namespace DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyConcreteProduct;
use DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyReader;
// 配列の読み込みを行うクラス
class ArrayReader implements MyReader
{
// 変数をプロパティとして保管
private $data;
// コンストラクタ
public function __construct($data)
{
$this->data_name = $data;
}
// 型を表示する
public function display_type()
{
echo 'このデータの型は'.gettype($this->data_name).'です'."<br>"."\n";
}
// 配列を改行区切りで表示する
public function display_data()
{
foreach ($this->data_name as $value) {
echo $value."<br>"."\n";
}
}
}
StringReader.php
StringReader.php
<?php
namespace DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyConcreteProduct;
use DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyReader;
// 文字列の読み込みを行うクラス
class StringReader implements MyReader
{
// 変数をプロパティとして保管
private $data;
// コンストラクタ
public function __construct($data)
{
$this->data_name = $data;
}
// 型を表示する
public function display_type()
{
echo 'このデータの型は'.gettype($this->data_name).'です'."<br>"."\n";
}
// 文字列を表示する
public function display_data()
{
echo $this->data_name."<br>"."\n";
}
}
Virtual Constructor(仮想的なコンストラクタ)
とも呼ばれている。Template Methodパターン
の代表的な適用例である。factory method
とも呼ばれる。処理の流れ
- 渡した変数の型(配列か文字列か)でオブジェクトのクラスを分ける。表示方法は同じ。
-
MyReaderFactoryクラス
はオブジェクト生成のメソッドを提供する。クライアントとの接点。(Creatorクラス) - クライアント側(
my_client.php
)から上記のオブジェクトを生成する。 -
MyReaderクラス
でオブジェクト生成に必要な枠(API)を提供する。(Productクラス) -
ArrayReaderクラス
とStringReaderクラス
でMyReaderクラスに決められた枠を実装し、それぞれのオブジェクトを生成する。(ConcreteProductクラス) - 今回はConcreteCreatorクラスに該当するクラスはなし。
ファイル構造
MyFactoryMethod
├── MyConcreteProduct
│ ├── ArrayReader.php
│ └── StringReader.php
├── MyReader.php
├── MyReaderFactory.php
└── my_client.php
ソースコード
my_client.php
my_client.php
<?php
namespace DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod;
require dirname(dirname(__DIR__)).'/vendor/autoload.php';
use DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyReaderFactory;
// 型の違う3つのデータを用意する
$array_data = array('apple', 'orange', 'peach', 'banana');
$string_data = 'fruits';
$int_data = 123;
// 変数の内容を表示させる
function show($data)
{
// 結果としてMyReaderクラスのインスタンスが生成される
// 型別のインスタンスが返される
$factory = new MyReaderFactory();
$data = $factory->create($data);
// 型を表示する
$data->display_type();
// 変数の内容を表示する
$data->display_data();
}
// 型別に実行する
show($array_data);
show($string_data);
show($int_data);
MyReaderFactory.php
MyReaderFactory.php
<?php
namespace DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod;
use DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyReader;
use DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyConcreteProduct\ArrayReader;
use DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyConcreteProduct\StringReader;
// MyReaderクラスのインスタンス生成を行うクラス
class MyReaderFactory
{
// MyReaderクラスのインスタンスを生成する
public function create($data)
{
$reader = $this->createReader($data);
return $reader;
}
// 変数の型からMyReaderクラスのサブクラスを判定する
// 変数の型にあったインスタンスを生成する
private function createReader($data)
{
if (is_array($data)) {
return new ArrayReader($data);
} elseif (is_string($data)) {
return new StringReader($data);
} else {
die(gettype($data).'型はサポートしていません');
}
}
}
MyReader.php
MyReader.php
<?php
namespace DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod;
// 読み込み機能を表すインターフェイス
// メソッドはサブクラスで実装される
interface MyReader
{
// 型を表示する
public function display_type();
// 変数の内容を表示する
public function display_data();
}
ArrayReader.php
ArrayReader.php
<?php
namespace DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyConcreteProduct;
use DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyReader;
// 配列の読み込みを行うクラス
class ArrayReader implements MyReader
{
// 変数をプロパティとして保管
private $data;
// コンストラクタ
public function __construct($data)
{
$this->data_name = $data;
}
// 型を表示する
public function display_type()
{
echo 'このデータの型は'.gettype($this->data_name).'です'."<br>"."\n";
}
// 配列を改行区切りで表示する
public function display_data()
{
foreach ($this->data_name as $value) {
echo $value."<br>"."\n";
}
}
}
StringReader.php
StringReader.php
<?php
namespace DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyConcreteProduct;
use DoYouPhp\PhpDesignPattern\FactoryMethod\MyFactoryMethod\MyReader;
// 文字列の読み込みを行うクラス
class StringReader implements MyReader
{
// 変数をプロパティとして保管
private $data;
// コンストラクタ
public function __construct($data)
{
$this->data_name = $data;
}
// 型を表示する
public function display_type()
{
echo 'このデータの型は'.gettype($this->data_name).'です'."<br>"."\n";
}
// 文字列を表示する
public function display_data()
{
echo $this->data_name."<br>"."\n";
}
}
Author And Source
この問題について(【PHPデザインパターン】04_Factory Method~生成処理と使用処理を分離する), 我々は、より多くの情報をここで見つけました https://qiita.com/yukibe/items/61644c4960dbf9778da9著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .