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

抽丝剥茧——访问者设计模式

作者头像
石的三次方
发布2021-01-05 22:30:32
2230
发布2021-01-05 22:30:32
举报
文章被收录于专栏:石的三次方石的三次方

访问者设计模式

兄弟们好,今天我们来聊一下访问者设计模式

说实话,这个设计模式花费了我挺长时间的,比较晦涩难懂。同时这个设计模式在我们的业务中应用场景也不是很多,不过呢,这么贴心的我,当然要尽可能的用大白话去给兄弟们好好的聊聊这个设计模式。

我们先从名字上聊聊:「访问者设计模式」,有一个访问者,所以呢,它应该是用来访问对象的,访问对象最常见的方式就是我们的get/set方法了,另外呢,对于多个对象,例如「数组,集合等等」,访问方式可以存在一个遍历,不过这种方式,往往会有一个问题,就是**不同的访问者可能想要对这个对象做不同的事情。**就比如对于一个漂亮的小姐姐,我和屏幕前的行为肯定可能不一样,屏幕前的你会绅士的过去搭讪,要微信等等,而我这个lsp,估计就看看就走了(官方认证,哈哈哈)。所以呢,「我们需要这个对象给不同的人提供不同的应对方式」

这个时候,可能有的兄弟想起了一个设计模式,「没错,就是迭代器设计模式」,这个设计模式就是用来对不同的集合容器进行遍历的,我们可以通过定义不同的迭代器来实现对对象的访问。不过它的作用有限,「它不能对对象的行为进行修改,它仅仅可以拿到这个对象原本的处理方式。」

这个时候,有兄弟又说了,可以修改对象的行为,这不是代理模式或者装饰者设计模式嘛?不过通过这两模式的确可以实现我们的需求,不过还有另一种设计模式,就是我们今天的访问者设计模式,它提供了另外一种实现这种需求的方式。

访问者设计模式的思想:「所有可以被访问的对象,都会声明一个accept方法,用来定义哪些访问者可以访问这个对象 ,所有的访问者对象都自己实现一套访问这些对象的方法。当访问者进行访问的时候,调用器调用accept方法,这个时候会通过遍历的方式,调用每一个可以被访问对象的accept方法,进而调用访问者对象定义的对这个对象的访问方法。」

「一个伪图,更加便于大家理解:」

「我们再来看一下它的具体类图实现:」

「角色划分:」

  • 抽象访问者。定义了关于所以可以被访问的功能方法。(Visitor)
  • 具体的访问者。定义了该访问者访问这些被访问对象的特定方式。(Convistor
  • 元素对象。定义了可以访问对象的accept方法。Element
  • 具体被访问者。实现了元素对象,重写了accept方法,实现元素对象。Small,Big
  • 控制器。用来控制增加或者删除可以被访问对象和具体的访问者访问被访问者,实现元素对象。(ElementController)

「具体代码实现:」

「抽象访问者:」

代码语言:javascript
复制
abstract class Vistor{
    abstract void vistorTom(Tom tom);
    abstract void vistorJack(Jack jack);
}

「具体的访问者:」

代码语言:javascript
复制
class StuVistor extends Vistor{
    @Override
    void vistorTom(Tom tom) {
        tom.name="stu1" ;
        System.out.println("这是学生访问者"+tom.name);
    }

    @Override
    void vistorJack(Jack jack) {
        jack.name="jack1";
        System.out.println("这是Jack访问者"+jack.name);
    }
}

「元素对象:」

代码语言:javascript
复制
interface Element{
    void accept(Vistor vistor);
}

「被访问者:」

代码语言:javascript
复制
class Tom implements Element{
    String name ;
    String age ;

    @Override
    public void accept(Vistor vistor) {
        vistor.vistorTom(this);
    }
}
class Jack implements Element{
    String name ;
    String age ;

    @Override
    public void accept(Vistor vistor) {
        vistor.vistorJack(this);
    }
}

「控制器:」

代码语言:javascript
复制
class ConElement implements Element{

    private List<Element> lists = new LinkedList<>();

    @Override
    public void accept(Vistor vistor) {
        for (int i = 0; i < lists.size(); i++) {
            lists.get(i).accept(vistor);
        }
    }

    public ConElement addVistor(Element element){
        lists.add(element);
        return this ;
    }
}

「客户端:」

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


    public static void main(String[] args) {
        Element element = new ConElement().addVistor(new Jack()).addVistor(new Tom());

        StuVistor stuVistor = new StuVistor();
        element.accept(stuVistor);
    }
}

好啦,今天的设计模式就到这里了。我们明天再见。兄弟们,晚安呀。

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

本文分享自 石的三次方 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 访问者设计模式
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档