前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >行为型设计模式:访问者模式

行为型设计模式:访问者模式

作者头像
jinjunzhu
发布2020-08-20 15:41:23
2730
发布2020-08-20 15:41:23
举报
文章被收录于专栏:个人开发个人开发

访问者模式是设计模式中最难理解的一种设计模式,代码也比较复杂。在GOF《设计模式》中ding定义如下:

Allows for one or more operation to be applied to a set of objects at runtime, decoupling the operations from the object structure.

用于一个或多个从操作应用于一组对象,解耦对象和操作。下面看一下代码。UML类图如下:

上图中,有2个访问者VisitorA和VisitorB,它们要操作一组对象,VisitableA、VisitableB和VisitableC。

访问者接口和实现类:

代码语言:javascript
复制
public interface Visitor {

    void visit(VisitableA visitableA);

    void visit(VisitableB visitableB);

    void visit(VisitableC visitableC);
}

public class VisitorA implements Visitor{

    @Override
    public void visit(VisitableA visitableA) {
        System.out.println("visitorA visit A");
    }

    @Override
    public void visit(VisitableB visitableB) {
        System.out.println("visitorA visit B");
    }

    @Override
    public void visit(VisitableC visitableC) {
        System.out.println("visitorA visit C");
    }
}

public class VisitorB implements Visitor{

    @Override
    public void visit(VisitableA visitableA) {
        System.out.println("visitorB visit A");
    }

    @Override
    public void visit(VisitableB pdfFile) {
        System.out.println("visitorB visit B");
    }

    @Override
    public void visit(VisitableC pdfFile) {
        System.out.println("visitorB visit C");
    }
}

下面是被访问者类:

代码语言:javascript
复制
public abstract class AbstractVisitable {

    abstract public void accept(Visitor visitor);

}

public class VisitableA extends AbstractVisitable {

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

}

public class VisitableB extends AbstractVisitable {

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

}

public class VisitableC extends AbstractVisitable {

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}上面代码中accept方法,调用了访问者来访问自己,是一个最关键的地方。

下面是应用类:

代码语言:javascript
复制
public class Application {

    public static void main(String[] args) {
        List<AbstractVisitable> abstractVisitables = new ArrayList<>();
        abstractVisitables.add(new VisitableA());
        abstractVisitables.add(new VisitableB());
        abstractVisitables.add(new VisitableC());

        VisitorB visitorB = new VisitorB();
        VisitorA visitorA = new VisitorA();
        for (AbstractVisitable abstractVisitable : abstractVisitables) {
            abstractVisitable.accept(visitorA);
            abstractVisitable.accept(visitorB);
        }
    }
}

访问者模式的思想是让操作和操作对象解耦,如上代码,如果我们要增加一个访问操作,只需要增加一个Visitor的实现类即可。

举个实际应用的例子,我们有3组数据,分别来自不用的数据源,但是它们都是来自贷款业务的不同业务系统,具有贷款业务特性。我们现在要分别对这3组数据抽取出类似于客户、贷款额度、还款状态等类似,这样我们就可以使用上面的设计模式。把3组数据作为被访问者,抽取客户、抽取贷款额度、抽取还款状态作为访问者。

因为访问者模式实现起来比较复杂,在实际开发中使用需要谨慎。可以用策略模式来取代,比如上面的访问者改为策略接口类,接口类中定义visitA和visitB方法,根据不同被访问者实现上面的接口来定义策略类,然后策略工厂根据被访问者不同选择不同的策略类。代码如下:

代码语言:javascript
复制
public interface Strategy {

    void visitA();

    void visitB();
}

public class StrategyA implements Strategy {

    @Override
    public void visitA() {
        System.out.println("visitorA visit A");
    }

    @Override
    public void visitB() {
        System.out.println("visitorB visit A");
    }
}

public class StrategyB implements Strategy {

    @Override
    public void visitA() {
        System.out.println("visitorA visit B");
    }

    @Override
    public void visitB() {
        System.out.println("visitorB visit B");
    }
}

public class StrategyC implements Strategy {

    @Override
    public void visitA() {
        System.out.println("visitorA visit C");
    }

    @Override
    public void visitB() {
        System.out.println("visitorB visit C");
    }
}
代码语言:javascript
复制

本文代码地址:https://github.com/jinjunzhu/design-pattern.git

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 jinjunzhu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档