Visitor パターンは、実際には、外部クラスがツリー構造の各ノードのオブジェクトを取得し、各オブジェクトを操作できるようにするパターンで、元のツリー構造を変更せずに、統計などの機能を拡張できます。
このモードでは、いくつかの要素が存在する必要があります:
1. 特定の要素オブジェクト、訪問者が実際に訪問したい場所 (つまり、ノード)
2. 安定したツリー構造各ノードは要素オブジェクトであり、通常は組み合わせモードで、訪問者がアクセスできる実際の場所を提供します (つまり、訪問者は特定の属性構造内のノードのインスタンス化オブジェクトにアクセスします)。訪問者インターフェイス。ここでは訪問者のインターフェイス メソッドを定義します。これは、訪問者が現在のノードにアクセスできるように、ノードで訪問者を参照するために使用されるメソッドです。
4. ビジターの特定の実装は、ビジターインターフェースを継承してインターフェースメソッドを実装します
//定义元素接口 abstract class User { public function getPoint() { return rand();//改数据应该由数据库中读取,这里就直接模拟某个值了、 } //这里的accept方法用于把访问者引入,在这个方法里,$visitor访问者可以通过User类获取需要的数据进而进行相应的操作。 abstract function accept(UserVisitor $visitor); } //定义元素接口 class VipUser extends User { //在这里getPoint()具体实现就由接口中实现了 //在这里就把当前对象传递给了visitor访问者,在访问者类的visitVip方法中就能根据$this获取必要的数据进行相应的操作 public function accept(UserVisitor $vitor) { $vitor->visitVip($this); } } class NormalUser extends User { //同上的getPoint()具体实现就由接口中实现了 //同VipUser类中的accept public function accept(UserVisitor $vitor) { $vitor->visitNormal($this); } } //定义访问者接口 abstract class UserVisitor { //访问者必须要实现的访问不同用户的接口方法 abstract function visitVip(User $user); abstract function visitNormal(User $user); } //积分操作的访问者实现 class PointActVisitor extends UserVisitor { public function visitVip(User $user) { echo 'Vip用户+10分<br/>'; } public function visitNormal(User $user) { echo 'Normal用户+5分<br/>'; } } //用户树形结构 class Users { protected $users; public function addUser(User $user) { $this->users[] = $user; } }