【PHPデザインパターン】14_Flyweight~同じものは一度しか作らない
引用記事
この記事を書くきっかけになったブログです。
記事内の解説やソースコードは、こちらのブログと著者の公開リポジトリを参考にしています。
Do You PHP はてな〜[doyouphp][phpdp]PHPによるデザインパターン入門 - Flyweight~同じものは一度しか作らない
概要
- 一度インスタンス化したオブジェクトを使い回し、生成されるオブジェクトの数やリソースの消費を抑える。
- 環境や状況によって変化しない情報は「intrinsic」(「本質的な」の意)、変化する情報は「extrinsic」(「非本質的な」の意)と呼ばれる。
- Flyweightパターンでは、intrinsicな情報を持つオブジェクトが共有される。
構成要素
Flyweightクラス
- 共有するオブジェクトの共通APIを定義する。
ConcreteFlyweightクラス
- Flyweightクラスのサブクラス。
- このクラスのインスタンスが共有されるので、intrinsicな情報のみ保持するようにする。
UnsharedConcreteFlyweightクラス
- Flyweightクラスのサブクラス。
- このクラスのインスタンスは共有されないので、extrinsicな情報を保持しても構わない。
FlyweightFactoryクラス
- Flyweight型のインスタンスを生成・保持するクラス。
Clientクラス
- Flyweight型のオブジェクトへの参照を保持するクラス。
ObjectPoolパターン
- オブジェクトの数を制限して再利用する。
- Flyweightパターンとの共通点が多い。
- GoFパターンではない。
実演
処理の流れ
- Itemクラスのオブジェクトは、ItemFactoryクラスのメソッドからのみ呼び出せる。
- オブジェクトが存在しない場合のみ、新規にオブジェクトを作成する。
- UnsharedConcreteFlyweightクラスは、今回作成しない。
ファイル構造
MyFlyweight
├── Item.php
├── ItemFactory.php
└── my_client.php
ソースコード
Flyweightクラス
処理の流れ
- Itemクラスのオブジェクトは、ItemFactoryクラスのメソッドからのみ呼び出せる。
- オブジェクトが存在しない場合のみ、新規にオブジェクトを作成する。
- UnsharedConcreteFlyweightクラスは、今回作成しない。
ファイル構造
MyFlyweight
├── Item.php
├── ItemFactory.php
└── my_client.php
ソースコード
Flyweightクラス
兼ConcreteFlyweightクラス。
Item.php
Item.php
<?php
namespace DoYouPhp\PhpDesignPattern\Flyweight\MyFlyweight;
/**
* FlyweightクラスとConcreteFlyweightクラスに相当する
*/
class Item
{
private $id;
private $name;
private $price;
// 各プロパティをセットする
public function __construct($id, $name, $price)
{
$this->id = $id;
$this->name = $name;
$this->price = $price;
}
// 各要素を返すメソッド
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function getPrice()
{
return $this->price;
}
}
FlyweightFactoryクラス
ItemFactory.php
ItemFactory.php
<?php
namespace DoYouPhp\PhpDesignPattern\Flyweight\MyFlyweight;
use DoYouPhp\PhpDesignPattern\Flyweight\MyFlyweight\Item;
/**
* FlyweightFactoryクラスに相当する
* Singletonパターンにもなっている
*/
class ItemFactory
{
private $pool;
private static $instance = null;
// コンストラクタ
// 配列型のテスト用データからItemクラスのインスタンスを作成する
private function __construct($data_array)
{
$this->buildPool($data_array);
}
// ItemFactoryクラスのインスタンスを返す
// 同時にItemクラスのインスタンスが作成される
// ItemFactoryクラスのインスタンスは、このメソッドからのみ返される
public static function getInstance($data_array)
{
if (is_null(self::$instance)) {
self::$instance = new ItemFactory($data_array);
}
return self::$instance;
}
// 引数のidに該当するItemクラスのインスタンスを返す
public function getItem($id)
{
if (array_key_exists($id, $this->pool)) {
return $this->pool[$id];
} else {
return;
}
}
// 配列型のテスト用データを読み込み、Itemクラスのインスタンスを作成する
// $poolはItemクラスのインスタンスを要素とする配列
private function buildPool($data_array)
{
$this->pool = array();
foreach ($data_array as $data) {
$item_id = $data['id'];
$item_name = $data['name'];
$price = $data['price'];
$this->pool[$item_id] = new Item($item_id, $item_name, $price);
}
}
// インスタンスの複製を防ぐ
final public function __clone()
{
throw new \RuntimeException(get_class($this).'クラスのインスタンスは複製できません');
}
}
Clientクラス
my_client.php
my_client.php
<?php
namespace DoYouPhp\PhpDesignPattern\Flyweight\MyFlyweight;
require dirname(dirname(__DIR__)).'/vendor/autoload.php';
use DoYouPhp\PhpDesignPattern\Flyweight\MyFlyweight\ItemFactory;
// id,name,priceを表示する
function dumpData($data)
{
foreach ($data as $object) {
echo 'id:'.$object->getId().',name:'.$object->getName().',price:'.$object->getPrice().'<br>'."\n";
}
}
// 配列型のテスト用データ
$data_array = array(
array('id' => 1, 'name' => apple, 'price' => 100),
array('id' => 2, 'name' => orange, 'price' => 80),
array('id' => 3, 'name' => banana, 'price' => 130)
);
// ItemFactoryクラスのインスタンス作成と呼び出しを行う
$factory = ItemFactory::getInstance($data_array);
// idを引数にして、対応するItemクラスのインスタンスを取得する
// 配列itemsの要素としてセットする
$items = array();
$items[] = $factory->getItem(1);
$items[] = $factory->getItem(2);
$items[] = $factory->getItem(3);
// idが同じであれば、既存のオブジェクトと同じものである
if ($items[0] === $factory->getItem(1)) {
echo '同一のオブジェクトです'.'<br>'."\n";
} else {
echo '同一のオブジェクトではありません'.'<br>'."\n";
}
// 取得したデータのプロパティを出力する
dumpData($items);
// ItemFactoryクラスのオブジェクトは複製できないことを確認する
try {
$factory_clone = clone $factory;
} catch (\RuntimeException $e) {
echo $e->getMessage().'<br>'."\n";
}
Author And Source
この問題について(【PHPデザインパターン】14_Flyweight~同じものは一度しか作らない), 我々は、より多くの情報をここで見つけました https://qiita.com/yukibe/items/53fbae731ad952dc7185著者帰属:元の著者の情報は、元の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 .