终于搞定,累成一滩,今晚不想说话。
<?php /* The visitor design pattern is a way of separating an algorithm from an object structure on which it operates. As a result, we are able to add new operations to existing object structures without actually modifying those structures. */ interface RoleVisitorInterface { public function visitUser(User $role); public function visitGroup(Group $role); } class RolePrintVisitor implements RoleVisitorInterface { public function visitGroup(Group $role) { echo 'Role: ' . $role->getName() . '<br/>'; } public function visitUser(User $role) { echo 'Role: ' . $role->getName() . '<br/>'; } } abstract class Role { 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); } } class User extends Role { protected $name; public function __construct($name) { $this->name = (string)$name; } public function getName() { return 'User ' . $this->name . '<br/>'; } } class Group extends Role { protected $name; public function __construct($name) { $this->name = (string)$name; } public function getName() { return 'Group ' . $this->name . '<br/>'; } } $group = new Group('my group'); $user = new User('my user'); $visitor = new RolePrintVisitor(); $group->accept($visitor); $user->accept($visitor); ?>