【PHPデザインパターン】23_Visitor~要素と要素に対する操作を分離する
引用記事
この記事を書くきっかけになったブログです。
記事内の解説やソースコードは、こちらのブログと著者の公開リポジトリを参考にしています。
Do You PHP はてな〜[doyouphp][phpdp]PHPによるデザインパターン入門 - Visitor~要素と要素に対する操作を分離する
概要
- 「visitor」は「訪問者」という意味。
- データ構造上の要素とそれに対する操作を分離する。
- データ構造から分離された「操作」がデータ構造を渡り歩き、順に処理を行っていく。
構成要素
Visitorクラス
- 操作のクラス階層で最上位に位置するクラス。
ConcreteVisitorクラス
- Visitorクラスのサブクラス。
Elementクラス
- データ構造のクラス階層で最上位に位置するクラス。
- Visitor型のオブジェクトを受け入れるためのメソッドを宣言する。
ConcreteElementクラス
- Elementクラスのサブクラス。
ObjectStructureクラス
- Elementクラスの集合を表すクラス。
実演
処理の流れ
-
ItemObjArray型オブジェクト
をデータ構造とする。プロパティとして、stdClass型オブジェクト
を要素とする配列を保持している。
-
ItemObjArrayクラス
でVistor型オブジェクトを受け入れるメソッドを用意する。
-
DumpVisitorクラス
から各要素のプロパティを出力する。
-
CountVisitorクラス
から要素数を出力する。
- 今回はConcreteElementクラスを作成していない。
ファイル構造
MyVisitor
├── CountVisitor.php
├── DumpVisitor.php
├── ItemObjArray.php
├── Visitor.php
└── my_client.php
ソースコード
Visitorクラス
Visitor.php
Visitor.php
<?php
namespace DoYouPhp\PhpDesignPattern\Visitor\MyVisitor;
use DoYouPhp\PhpDesignPattern\Visitor\MyVisitor\ItemObjArray;
/**
* Visitorクラスに相当する
*/
interface Visitor
{
public function visit(ItemObjArray $item_obj_array);
}
ConcreteVisitorクラス
DumpVisitor.php
DumpVisitor.php
<?php
namespace DoYouPhp\PhpDesignPattern\Visitor\MyVisitor;
use DoYouPhp\PhpDesignPattern\Visitor\MyVisitor\Visitor;
use DoYouPhp\PhpDesignPattern\Visitor\MyVisitor\ItemObjArray;
/**
* ConcreteVisitorクラスに相当する
*/
class DumpVisitor implements Visitor
{
// ItemObjArray型オブジェクトで保持しているstdClass型オブジェクトのプロパティを返す
public function visit(ItemObjArray $item_obj_array)
{
foreach ($item_obj_array->getObjArray() as $obj) {
echo $obj->item_name.'<br>'."\n";
}
}
}
CountVisitor.php
CountVisitor.php
<?php
namespace DoYouPhp\PhpDesignPattern\Visitor\MyVisitor;
use DoYouPhp\PhpDesignPattern\Visitor\MyVisitor\Visitor;
use DoYouPhp\PhpDesignPattern\Visitor\MyVisitor\ItemObjArray;
/**
* ConcreteVisitorクラスに相当する
*/
class CountVisitor implements Visitor
{
// ItemObjArray型オブジェクトで保持しているstdClass型オブジェクトの数を返す
public function visit(ItemObjArray $item_obj_array)
{
echo count($item_obj_array->getObjArray());
}
}
Elementクラス
処理の流れ
-
ItemObjArray型オブジェクト
をデータ構造とする。プロパティとして、stdClass型オブジェクト
を要素とする配列を保持している。 -
ItemObjArrayクラス
でVistor型オブジェクトを受け入れるメソッドを用意する。 -
DumpVisitorクラス
から各要素のプロパティを出力する。 -
CountVisitorクラス
から要素数を出力する。 - 今回はConcreteElementクラスを作成していない。
ファイル構造
MyVisitor
├── CountVisitor.php
├── DumpVisitor.php
├── ItemObjArray.php
├── Visitor.php
└── my_client.php
ソースコード
Visitorクラス
Visitor.php
Visitor.php
<?php
namespace DoYouPhp\PhpDesignPattern\Visitor\MyVisitor;
use DoYouPhp\PhpDesignPattern\Visitor\MyVisitor\ItemObjArray;
/**
* Visitorクラスに相当する
*/
interface Visitor
{
public function visit(ItemObjArray $item_obj_array);
}
ConcreteVisitorクラス
DumpVisitor.php
DumpVisitor.php
<?php
namespace DoYouPhp\PhpDesignPattern\Visitor\MyVisitor;
use DoYouPhp\PhpDesignPattern\Visitor\MyVisitor\Visitor;
use DoYouPhp\PhpDesignPattern\Visitor\MyVisitor\ItemObjArray;
/**
* ConcreteVisitorクラスに相当する
*/
class DumpVisitor implements Visitor
{
// ItemObjArray型オブジェクトで保持しているstdClass型オブジェクトのプロパティを返す
public function visit(ItemObjArray $item_obj_array)
{
foreach ($item_obj_array->getObjArray() as $obj) {
echo $obj->item_name.'<br>'."\n";
}
}
}
CountVisitor.php
CountVisitor.php
<?php
namespace DoYouPhp\PhpDesignPattern\Visitor\MyVisitor;
use DoYouPhp\PhpDesignPattern\Visitor\MyVisitor\Visitor;
use DoYouPhp\PhpDesignPattern\Visitor\MyVisitor\ItemObjArray;
/**
* ConcreteVisitorクラスに相当する
*/
class CountVisitor implements Visitor
{
// ItemObjArray型オブジェクトで保持しているstdClass型オブジェクトの数を返す
public function visit(ItemObjArray $item_obj_array)
{
echo count($item_obj_array->getObjArray());
}
}
Elementクラス
兼ObjectStructureクラス。
ItemObjArray.php
ItemObjArray.php
<?php
namespace DoYouPhp\PhpDesignPattern\Visitor\MyVisitor;
use DoYouPhp\PhpDesignPattern\Visitor\MyVisitor\Visitor;
/**
* Elementクラス兼ObjectStructureクラスに相当する
* Visitor型のオブジェクトを受け入れるためのメソッドを宣言する
*/
class ItemObjArray
{
private $item_obj_array;
// 配列の要素をstdClass型オブジェクト化して、配列型プロパティに加える
public function __construct($item_array)
{
$item_obj_array = array();
foreach($item_array as $item_name) {
$obj = new \stdClass();
$obj->item_name = $item_name;
$this->item_obj_array[] = $obj;
}
}
// 配列型プロパティを返す
public function getObjArray()
{
return $this->item_obj_array;
}
// Visitor型のオブジェクトを受け入れるためのメソッド
public function accept(Visitor $visitor)
{
$visitor->visit($this);
}
}
Client
my_client.php
my_client.php
<?php
namespace DoYouPhp\PhpDesignPattern\Visitor\MyVisitor;
require dirname(dirname(__DIR__)).'/vendor/autoload.php';
use DoYouPhp\PhpDesignPattern\Visitor\MyVisitor\DumpVisitor;
use DoYouPhp\PhpDesignPattern\Visitor\MyVisitor\CountVisitor;
// ItemObjArray型オブジェクトを生成する
$item_array = array('apple', 'orange', 'peach');
$item_obj_array = new ItemObjArray($item_array);
// ItemObjArray型オブジェクトで保持しているstdClass型オブジェクトのプロパティを返す
$item_obj_array->accept(new DumpVisitor());
// 同じインスタンスに対して別のVisitorを使用する
// ItemObjArray型オブジェクトで保持しているstdClass型オブジェクトの数を返す
$visitor = new CountVisitor();
$item_obj_array->accept($visitor);
Author And Source
この問題について(【PHPデザインパターン】23_Visitor~要素と要素に対する操作を分離する), 我々は、より多くの情報をここで見つけました https://qiita.com/yukibe/items/49fb3c53b42bb28cf68a著者帰属:元の著者の情報は、元の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 .