访问者模式

举报
小鲍侃java 发表于 2021/09/09 23:04:58 2021/09/09
【摘要】 定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。 优点:1.扩展性好。方便添加新的访问者。        ...

定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。

优点:1.扩展性好。方便添加新的访问者。

           2. 复用性好。可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度。

           3.灵活性好。访问者模式将数据结构与作用于结构上的操作解耦,使得操作集合可相对自由地演化而不影响系统的数据结构。

            4.符合单一职责原则。访问者模式把相关的行为封装在一起,构成一个访问者,使每一个访问者的功能都比较单一。

缺点:1.破坏封装。访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性。

            2.违反了依赖倒置原则。访问者模式依赖了具体类,而没有依赖抽象类。

            3、具体访问者元素变更比较困难。

使用场景:不同的人使用不同的方法,避免使用if-else。

原理:把需要调用的方法的实现写在调用者自己的类中,被调用者依赖于调用者。

类图:

在这里插入图片描述

实例代码

访问者接口

public interface Visitor {
    void visit(ConcreteElementA elementA);
    void visit(ConcreteElementB elementB);
}

访问者实现

public class ConcreteVisitorA implements Visitor {


    @Override
    public void visit(ConcreteElementA elementA) {

    }

    @Override
    public void visit(ConcreteElementB elementB) {

    }
}
public class ConcreteVisitorB implements Visitor {
    @Override
    public void visit(ConcreteElementA elementA) {

    }

    @Override
    public void visit(ConcreteElementB elementB) {

    }
}

抽象元素 一般定义一个accept方法

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

具体元素

public class ConcreteElementA implements Element {
    public void accept(Visitor visitor) {
        System.out.println("访问A");
        visitor.visit(this);
    }
}
public class ConcreteElementB implements Element {
    public void accept(Visitor visitor) {
        System.out.println("访问b");
        visitor.visit(this);
    }
}

ObjectStructure存放具体元素对象的集合

public class ObjectStructure {
    private List<Element> mElements = new ArrayList<>();

    public void addElement(Element e) {
        mElements.add(e);
    }

    public void removeElement(Element e) {
        mElements.remove(e);
    }

    public void accpet(Visitor visitor) {
        for (Element e : mElements) {
            e.accept(visitor);
        }
    }
}

调用

    ObjectStructure os = new ObjectStructure();
    os.addElement(new ConcreteElementA());
    os.addElement(new ConcreteElementB());
    //创建一个访问者
    Visitor visitor = new ConcreteVisitorA();
    os.accpet(visitor);

代码

访问者接口

public interface Visitor {

    void visit(Cavalry cavalry);

    void visit(Infantry infantry);
}

 

访问者实现

public class liyunlong implements Visitor{

    void visit(Cavalry cavalry){
      system.out.print("你们砍了多少鬼子啊" + cavalry.num)
    }

    void visit(Infantry infantry){
       system.out.print("你们砍了多少鬼子啊" + infantry.num)
}
}
public class zhaogang implements Visitor{

    void visit(Cavalry cavalry){
      system.out.print("你们背了多少条例啊" + cavalry.num)
    }

    void visit(Infantry infantry){
      system.out.print("你们背了多少条例啊" + infantry.num)
}
}

具体元素接口

public interface Element {

    // 核心方法,接受Visitor的访问
    public void accept(Visitor visitor);
}

具体元素实现

public class Cavalry implements Element {

    private int num;
    //构造方法
    public void accept(Visitor visitor) {
        System.out.println("骑兵");
        visitor.visit(this);
    }
}
public class Infantry implements Element {
     private int num;
    //构造方法
    public void accept(Visitor visitor) {
        System.out.println("步兵");
        visitor.visit(this);
    }
}

管理类

public class ObjectStructure {
    private List<Element> mElements = new ArrayList<>();

    public void addElement(Element e) {
        mElements.add(e);
    }

    public void removeElement(Element e) {
        mElements.remove(e);
    }

    public void accpet(Visitor visitor) {
        for (Element e : mElements) {
            e.accept(visitor);
        }
    }
}

调用

    ObjectStructure os = new ObjectStructure();
    os.addElement(new Cavalry(10));
    os.addElement(new Infantry(22));
    //创建一个访问者
    Visitor visitor = new liyunlong();
    os.accpet(visitor);

 

经典实现场景

https://www.cnblogs.com/edisonchou/p/7247990.html

文章来源: baocl.blog.csdn.net,作者:小黄鸡1992,版权归原作者所有,如需转载,请联系作者。

原文链接:baocl.blog.csdn.net/article/details/102755421

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。