robertogallea / laravel-visitor
Laravel的访问者模式实现
Requires
- illuminate/support: ^5.8.3|^6.0.0
Requires (Dev)
- mockery/mockery: dev-master
- phpunit/phpunit: ^8.2
This package is auto-updated.
Last update: 2024-09-04 17:50:38 UTC
README
1. 简介
LaravelVisitor是Laravel的一个访问者设计模式实现。它允许轻松地对任意元素的集合执行处理,无需使用重复的条件语句,从而提高代码的抽象性。
没有访问者
public function process() { $result = ''; foreach ($this->elements as $element) { if ($element instanceof FooClass) { $result .= ((FooClass)$element)->getData(); } elseif ($element instanceof BarClass) { $result .= ((BarClass)$element)->getData(); } elseif ($element instanceof BazClass) { $result .= ((BazClass)$element)->getData(); } } }
有访问者
public function process() { $visitor = new MyVisitor([ new FooClass(), new BarClass(), new BazClass(), ]); $visitor->execute(); $result = $visitor->getResult(); }
所有复杂性都隐藏在必须定义处理类方法的MyVisitor
类中。在上面的示例中,MyVisitor
将实现如下
class MyVisitor extends Visitor { private $result; public function getResult() { return $this->result; } public function visitFooClass(FooClass $fooClass) { $this->result .= ... ; } public function visitBarClass(BarClass $fooClass) { $this->result .= ... ; } public function visitBazClass(BazClass $fooClass) { $this->result .= ... ; } }
此外,这也强制执行了SRP原则,因为领域对象不需要实现表示方法,这些方法仅是访问者类实现的职责(尤其是如果需要多个的话)。
2. 安装
通过composer安装包
composer require robertogallea/laravel-visitor
3. 使用
为了使用此包,您需要定义至少一个Visitor
类和一些Visitee
类。
3.1. Visitee
实现
Visitee
的唯一要求是使用Visitable
特质,这样您就可以使任何类可访问。
3.2. Visitor
实现
Visitor
类必须实现CanVisit
接口,并继承Visitor
抽象类,通过定义getResult()
方法。
此外,对于每个定义的Visitee
,您都必须实现一个自定义的处理方法。例如,如果您有一个Book
Visitee
,您必须定义以下方法
public function visitBook(Book $book) { ... }
3.3. Visitor
生成
要生成Visitor
,您可以运行以下Artisan命令
php artisan make:visitor MyVisitor
该命令默认将类创建在Visitors
文件夹中。
4. 示例使用
4.1. Visitee
实现
Magazine.php
use robertogallea\LaravelVisitor\Models\Visitable; class Magazine { use Visitable; private $title; private $month; private $year; public function __construct($title, $month, $year) { $this->title = $title; $this->month = $month; $this->year = $year; } public function getTitle() { return $this->title; } public function getMonth() { return $this->month; } public function getYear() { return $this->year; } }
4.2. Visitor
实现
XMLVisitor.php
use robertogallea\LaravelVisitor\Models\Visitor; class XMLVisitor extends Visitor { private $xml = ''; public function visitMagazine(Magazine $magazine) { $this->xml .= '<magazine title="' . $magazine->getTitle() . '" ' . 'issue="' . $magazine->getMonth() . ' ' . $magazine->getYear() . '"></magazine>' . PHP_EOL; } public function getResult() { return $this->xml; } }
4.3. 客户端代码
$xmlCatalog = new XMLVisitor([ new Magazine('PHP programming', 'July', 2019) new Magazine('The art of woodworking', 'August', 2019) ]); $xmlCatalog->execute(); echo($xmlCatalog->getResult());
将生成以下输出
<magazine title="PHP programming" issue="July 2019"></magazine> <magazine title="The art of woodworking" issue="August 2019"></magazine>
5. 问题、问题和拉取请求
您可以在问题部分报告问题并提出问题。请以ISSUE:
开始您的问题,并以QUESTION:
开始您的问题。
如果您有问题,请首先检查已关闭的问题。
要提交拉取请求,请首先从本仓库派生,创建一个新分支,并将您的新/更新代码提交到该分支。然后从您的分支打开拉取请求。有关更多信息,请参阅本指南。