java设计模式之访问者(三)-经典访问者

上一讲描述了耦合在节点内部的访问者,访问逻辑放在每个节点之中,不方便维护和修改

今天我们描述经典的访问者模式

UML图如下

简单描述下,要实现一个家谱类Genealogy的遍历,家谱包含所有家族成员,包括爷爷、爸爸、叔叔、我和弟弟

首先会实现一个Element的接口,里面只有一个accept方法。所有节点实现这个接口表示是可接受访问的。

然后实现一个访问者的接口Visitor,包含了访问所有节点的方法。所有实际访问者都要实现这个接口实现自己的访问逻辑。

先把节点类展示下

public interface Element {
    void accept(Visitor visitor);
}

@Data
@NoArgsConstructor
public class GrandFather implements Element {
    //景点
    private Father father;
    private Uncle uncle;

    public GrandFather(Father father, Uncle uncle) {
        this.father = father;
        this.uncle = uncle;
    }


    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

@Data
@NoArgsConstructor
public class Father  implements Element {
    private Me me;
    private Brother brother;

    public Father(Me me, Brother brother) {
        this.me = me;
        this.brother = brother;
    }


    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

@AllArgsConstructor
@Data
public class Uncle implements Element {

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

@AllArgsConstructor
@Data
public class Me  implements Element {

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

@Data
public class Brother implements Element {

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

下面是访问者接口和它的实现类,可以看到所有的访问逻辑已经都集中到了访问者这里。

public interface Visitor {
    void visit(GrandFather node);

    void visit(Father node);

    void visit(Uncle node);

    void visit(Me node);

    void visit(Brother node);
}


public class VisitorImpl implements Visitor{
    @Override
    public void visit(GrandFather node) {
        System.out.println("I am GrandFather!");
        node.getFather().accept(this);
        node.getUncle().accept(this);
    }

    @Override
    public void visit(Father node) {
        System.out.println("I am Father!");
        node.getMe().accept(this);
        node.getBrother().accept(this);
    }

    @Override
    public void visit(Uncle node) {
        System.out.println("I am uncle!");
    }

    @Override
    public void visit(Me node) {
        System.out.println("I am me!");
    }

    @Override
    public void visit(Brother node) {
        System.out.println("I am brother!");
    }
}

定义一个家谱类

//家谱类
@Data
public class Genealogy {
    private Element root;
}

//访问家谱
public class Client {
    public static void main(String[] args) {
        GrandFather grandFather = new GrandFather();
        Father father = new Father();
        Uncle uncle = new Uncle();
        Me me = new Me();
        Brother brother = new Brother();
        grandFather.setFather(father);
        grandFather.setUncle(uncle);
        father.setBrother(brother);
        father.setMe(me);
        Genealogy genealogy = new Genealogy();
        genealogy.setRoot(grandFather);
        VisitorImpl visitor = new VisitorImpl();
        visitor.visit((GrandFather)genealogy.getRoot());
    }
}

输出

I am GrandFather!
I am Father!
I am me!
I am brother!
I am uncle!

 

posted @ 2022-08-17 10:57  Mars.wang  阅读(26)  评论(0编辑  收藏  举报