PHP设计模式系列--访问者模式(Visitor)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了PHP设计模式系列--访问者模式(Visitor),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4384字,纯文字阅读大概需要7分钟。
内容图文
![PHP设计模式系列--访问者模式(Visitor)](/upload/InfoBanner/zyjiaocheng/205/a25b5c5e13074ed6bc2cbae1ee46194d.jpg)
1、模式定义
我们去银行柜台办业务,一般情况下会开几个个人业务柜台的,你去其中任何一个柜台办理都是可以的。我们的访问者模式可以很好付诸在这个场景中:对于银行柜台来说,他们是不用变化的,就是说今天和明天提供个人业务的柜台是不需要有变化的。而我们作为访问者,今天来银行可能是取消费流水,明天来银行可能是去办理手机银行业务,这些是我们访问者的操作,一直是在变化的。
访问者模式就是表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
2、UML类图
3、示例代码
RoleVisitorInterface.php
<?phpnamespace DesignPatterns\Behavioral\Visitor;/** * 访问者接口 */interface RoleVisitorInterface{ /** * 访问 User 对象 * * @param \DesignPatterns\Behavioral\Visitor\User $role */ public function visitUser(User $role); /** * 访问 Group 对象 * * @param \DesignPatterns\Behavioral\Visitor\Group $role */ public function visitGroup(Group $role);}
RolePrintVisitor.php
<?phpnamespace DesignPatterns\Behavioral\Visitor;/** * Visitor接口的具体实现 */class RolePrintVisitor implements RoleVisitorInterface{ /** * {@inheritdoc} */ public function visitGroup(Group $role) { echo "Role: " . $role->getName(); } /** * {@inheritdoc} */ public function visitUser(User $role) { echo "Role: " . $role->getName(); }}
Role.php
<?phpnamespace DesignPatterns\Behavioral\Visitor;/** * Role 类 */abstract class Role{ /** * 该方法基于Visitor的类名判断调用Visitor的方法 * * 如果必须调用其它方法,重写本方法即可 * * @param \DesignPatterns\Behavioral\Visitor\RoleVisitorInterface $visitor * * @throws \InvalidArgumentException */ public function accept(RoleVisitorInterface $visitor) { $klass = get_called_class(); preg_match('#([^\\\\]+)$#', $klass, $extract); $visitingMethod = 'visit' . $extract[1]; if (!method_exists(__NAMESPACE__ . '\RoleVisitorInterface', $visitingMethod)) { throw new \InvalidArgumentException("The visitor you provide cannot visit a $klass instance"); } call_user_func(array($visitor, $visitingMethod), $this); }}
User.php
<?phpnamespace DesignPatterns\Behavioral\Visitor;class User extends Role{ /** * @var string */ protected $name; /** * @param string $name */ public function __construct($name) { $this->name = (string) $name; } /** * @return string */ public function getName() { return "User " . $this->name; }}
Group.php
<?phpnamespace DesignPatterns\Behavioral\Visitor;class Group extends Role{ /** * @var string */ protected $name; /** * @param string $name */ public function __construct($name) { $this->name = (string) $name; } /** * @return string */ public function getName() { return "Group: " . $this->name; }}
4、测试代码
Tests/VisitorTest.php
<?phpnamespace DesignPatterns\Tests\Visitor\Tests;use DesignPatterns\Behavioral\Visitor;/** * VisitorTest 用于测试访问者模式 */class VisitorTest extends \PHPUnit_Framework_TestCase{ protected $visitor; protected function setUp() { $this->visitor = new Visitor\RolePrintVisitor(); } public function getRole() { return array( array(new Visitor\User("Dominik"), 'Role: User Dominik'), array(new Visitor\Group("Administrators"), 'Role: Group: Administrators') ); } /** * @dataProvider getRole */ public function testVisitSomeRole(Visitor\Role $role, $expect) { $this->expectOutputString($expect); $role->accept($this->visitor); } /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage Mock */ public function testUnknownObject() { $mock = $this->getMockForAbstractClass('DesignPatterns\Behavioral\Visitor\Role'); $mock->accept($this->visitor); }}
5、总结
访问者模式适用于数据结构相对稳定的系统,它把数据结构和作用于结构之上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。在本例中,User、Group 是数据结构,而 RolePrintVisitor 是访问者(用于结构之上的操作)。
当实现访问者模式时,要将尽可能多的将对象浏览逻辑放在 Visitor 类中,而不是放在它的子类中,这样的话,ConcreteVisitor 类所访问的对象结构依赖较少,从而使维护较为容易。
内容总结
以上是互联网集市为您收集整理的PHP设计模式系列--访问者模式(Visitor)全部内容,希望文章能够帮你解决PHP设计模式系列--访问者模式(Visitor)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。