访问者模式

访问者模式介绍
访问者模式是一种将数据操作与数据结果分离的设计模式,在23中设计模式中最复杂的一个,使用频率不高。
访问这模式的基本想法是,软件系统中拥有一个由许多对象构成的、比较稳定的对象结构,这写对象的类都拥有一个accept方法用来接受访问者对象的访问。访问者是一个接口,它拥有一个visit方法,这个方法对访问到的对象结构中不同类型的元素做出不同的处理。在对象结构的一次访问过程中。我们遍历整个对象结构,对每一个元素都实施accept方法,在每一个元素的accept方法中会调用访问者的visit方法,从而使访问者得以处理对象结构的每一个元素,我们可针对对像结构设计不同的访问者类来完成不同的操纵,达到区别对待效果。
访问者模式的定义
封装一些作用于某种数据结构中的的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。
访问者模式的使用场景

  • 对象结构比较稳定,但经常需要在此对象结构上定义新的操作
  • 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免这些操作‘污染’这些对象的类,也不希望在增加新操作时修改这些类。

访问者模式的UML类图
这里写图片描述
这里写图片描述

代码示例:

接口
public interface Visitor {
    public void visit(GladiolusConcreteElement gladiolus);
    public void visit(ChrysanthemumConreteElement chrysanthemum);
}
接口
public interface FlowerElement {
    public void accept(Visitor visitor);
}
public class GladiolusVisitor implements Visitor {

    @Override
    public void visit(GladiolusConcreteElement gladiolus) {
        System.out.println(this.getClass().getSimpleName() + "  access  " + gladiolus.getClass().getSimpleName());
    }

    @Override
    public void visit(ChrysanthemumConreteElement chrysanthemum) {
        System.out.println(this.getClass().getSimpleName() + "  access  " + chrysanthemum.getClass().getSimpleName());
    }

}
public class GladiolusVisitor implements Visitor {

    @Override
    public void visit(GladiolusConcreteElement gladiolus) {
        System.out.println(this.getClass().getSimpleName() + "  access  " + gladiolus.getClass().getSimpleName());
    }

    @Override
    public void visit(ChrysanthemumConreteElement chrysanthemum) {
        System.out.println(this.getClass().getSimpleName() + "  access  " + chrysanthemum.getClass().getSimpleName());
    }

}
public class ChrysanthemumConreteElement implements FlowerElement {

    public void accept(Visitor visitor) {
        visitor.visit(this);//调用visitor里面的visit方法,传的是本对象的参数
    }

}
public class GladiolusConcreteElement implements FlowerElement {

    public void accept(Visitor visitor) {
        visitor.visit(this);//调用visitor里面的visit方法,传的是本对象的参数
    }

}
public class ObjectStructure {

    private final List<FlowerElement> elements = new ArrayList<>();
    //添加元素到集合
    public void addElement(final FlowerElement element){
        elements.add(element);
    }
    //在集合中删除指定元素
    public void removeElement(final FlowerElement e){
        elements.remove(e);
    }

    public void accept(final Visitor visitor){
        for(final FlowerElement e:elements){
        //调用的是FlowerElement实现类里面的accept方法,这个方法里面又是调用的是visitor对象里面的visit方法,传的是FlowerElement实现类的对象为参数,最后在visitor里面的visit方法处理逻辑,业务输出等
            e.accept(visitor);
        }
    }

}
public class Client {

    public static void main(String[] args) {
        final ObjectStructure os = new ObjectStructure();
        //往集合中添加元素
        os.addElement(new GladiolusConcreteElement());
        os.addElement(new ChrysanthemumConreteElement());
        //声明Visitor接口的实现类
        final GladiolusVisitor gVisitor = new GladiolusVisitor();
        final ChrysanthemumVisitor chVisitor = new ChrysanthemumVisitor();

        //调用了ObjectStructure结构管理类里面的accept方法,方法里面调用的是集合中FlowerElement接口实现类的accept方法
        os.accept(gVisitor);
        os.accept(chVisitor);

    }

}

运行结构:

GladiolusVisitor access GladiolusConcreteElement
GladiolusVisitor access ChrysanthemumConreteElement
ChrysanthemumVisitor access GladiolusConcreteElement
ChrysanthemumVisitor access ChrysanthemumConreteElement

总结
优点
1. 各角色职责分离,符号单一职责原则
2. 具有优秀的扩展性
3. 使得数据结构和作用于结构上的操作解耦,使得操作集合可以独立变化
4. 灵活性

缺点
1. 具体元素对访问这公布细节,违反了迪米特原则
2. 具体元素变更时导致修改成本大
3. 违反了依赖倒置原则,为了达到‘区别对待’而依赖了具体类,没有依赖抽象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
内容简介: 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 本课程内容定位学习设计原则,学习设计模式的基础。在实际开发过程中,并不是一定要求所有代码都遵循设计原则,我们要考虑人力、时间、成本、质量,不是刻意追求完美,要在适当的场景遵循设计原则,体现的是一种平衡取舍,帮助我们设计出更加优雅的代码结构。本章将详细介绍开闭原则(OCP)、依赖倒置原则(DIP)、单一职责原则(SRP)、接口隔离原则(ISP)、迪米特法则(LoD)、里氏替换原则(LSP)、合成复用原则(CARP)的具体内容。 为什么需要学习这门课程? 你在日常的开发中,会不会也遇到过同样的问题。系统出现问题,不知道问题究竟出在什么位置;当遇到产品需求,总是对代码缝缝补补,不能很快的去解决。而且平时工作中,总喜欢把代码堆在一起,出现问题时,不知道如何下手,工作效率很低,而且自己的能力也得不到提升。而这些都源于一个问题,那就是软件设计没做好。这门课能帮助你很好的认识设计模式,让你的能力得到提升。课程大纲: 为了让大家快速系统了解设计模式知识全貌,我为您总结了思维导图,帮您梳理学习重点,建议收藏!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值