訪問者パターンによって解決される問題
コード作成プロセスでは、いくつかの同様のオブジェクトにコードを追加する必要があることがよくあります。コンピューター オブジェクトの印刷コンポーネントを例に挙げてみましょう:
/** * 抽象基类 */ abstract class Unit { /** *获取名称 */ abstract public function getName(); } /** * Cpu类 */ class Cpu extends Unit { public function getName() { return 'i am cpu'; } } /** * 内存类 */ class Memory extends Unit { public function getName() { return 'i am memory'; } } /** * 键盘类 */ class Keyboard extends Unit { public function getName() { return 'i am keyboard'; } } /** * 计算机类 */ class Computer { protected $_items = []; public function add(Unit $unit) { $this->_items[] = $unit; } public function print() { // 循环打印各个组成部分 foreach ($this->_items as $item) { $item->getName(); } } }
現時点では、上記のとおりです。コードは完璧に見えますが、ここで問題が発生します。コンポーネントを出力するだけでなく、各コンポーネントの価格も出力する必要があります。 Unit 基本クラスに getPrice() メソッドと save() メソッドを追加すると、必要な機能を実現できますが、これを使用する場合にどのような追加操作を追加する必要があるかがわかりません。メソッドを使用して新しい操作を追加する必要があります。時間が経つにつれて、クラスはますます肥大化していきます。
訪問者パターンの実装
訪問者パターンは、データ構造とその構造に作用する操作を分離し、操作セットが比較的自由に進化できるようにするものです。以下のコード:
/** * 抽象基类 */ abstract class Unit { /** * 获取名称 */ abstract public function getName(); /** * 用来接受访问者对象,回调访问者的visit方法 * 非常关键的方法 */ public function accept(Visitor $visitor) { $method = visit . get_class($this); if (method_exists($visitor, $method)) { $visitor->$method($this); } } } /** * Cpu类 */ class Cpu extends Unit { public function getName() { return 'i am cpu'; } } /** * Memory类 */ class Memory extends Unit { public function getName() { return 'i am memory'; } } /** * Keyboard类 */ class Keyboard extends Unit { public function getName() { return 'i am keyboard'; } } /** * Keyboard类 */ interface Visitor { public function visitCpu(Cpu $cpu); public function visitMemory(Memory $memory); public function visitKeyboard(Keyboard $keyboard); } /** * */ class PrintVisitor implements Visitor { public function visitCpu(Cpu $cpu) { echo "hello, " . $cpu->getName() . "\n"; } public function visitMemory(Memory $memory) { echo "hello, " . $memory->getName() . "\n"; } public function visitKeyboard(Keyboard $keyboard) { echo "hello, " . $keyboard->getName() . "\n"; } } /** * */ class Computer { protected $_items = []; public function add(Unit $unit) { $this->_items[] = $unit; } /** * 调用各个组件的accept方法 */ public function accept(Visitor $visitor) { foreach ($this->_items as $item) { $item->accept($visitor); } } } $computer = new Computer(); $computer->add(new Cpu()); $computer->add(new Memory()); $computer->add(new Keyboard()); $printVisitor = new PrintVisitor(); $computer->print($printVisitor); // 以上的代码将打印出 hello, i am cpu hello, i am memory hello, i am keyboard
概要
上記の改善の後、データベースに新しい保存メソッドを追加する必要がある場合、Visitor クラスを実装する新しいメソッドを追加することが非常に簡単になりました。 SaveVisitor として、このクラスに save メソッドを実装することは、クラスとクラス内の一部の操作を分離することと同等であり、クラスの操作を収集するオブジェクトがビジターです。
以上がこの記事の全内容です。皆さんの学習に役立つことを願っています。また、皆さんも PHP 中国語 Web サイトをサポートしていただければ幸いです。
PHP デザインパターンの訪問者パターンを簡単にマスターすることに関するその他の記事については、PHP 中国語 Web サイトに注目してください。