방문자 패턴으로 해결되는 문제
코드 작성 과정에서 컴퓨터 개체의 인쇄 구성 요소를 예로 들어보겠습니다. :
/** * 抽象基类 */ 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
요약
위의 개선 후에는 확장이 매우 쉬워졌습니다. 데이터베이스에 저장하는 새 메서드를 추가해야 하는 경우 SaveVisitor와 같은 Visitor를 구현하는 새 클래스를 추가할 수 있습니다. 이 클래스에서 save 메서드를 구현하는 것은 이 클래스와 이 클래스의 일부 작업을 결합하는 것과 같습니다. , 클래스 연산을 수집하는 개체는 방문자입니다.
위 내용은 이 글의 전체 내용입니다. 모든 분들의 학습에 도움이 되기를 바랍니다.
PHP 디자인 패턴의 방문자 모드를 쉽게 익히는 것과 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!