【设计模式-行为型】访问者模式

一、什么是访问者模式

说起来访问者模式,其实很少用。我一直在思考该用什么样的例子把这个设计模式表述清晰,最近突然想到一个例子也许他就是访问者。港片有过很辉煌的年代,小的时候一直在看港片觉得拍的非常好,而且演员的演技也在线。 不知道大家看没有看过一个金典的穿越剧----《寻秦记》,其中的项少龙(古天乐)就是专业的访问者。项少龙的经历可以很好地体现访问者模式的核心思想。项少龙作为一个现代人,穿越到战国时期,他的角色可以被视为"访问者",而战国时期的各种人物和事件可以被视为"元素"。项少龙与这些元素的交互"不改变历史结构,添加新的操作",触发了一系列的变化和故事发展。

访问者模式在《寻秦记》中的体现

  1. 主角作为访问者 :项少龙从21世纪穿越到战国时期,他的任务是寻找并保护嬴政,确保历史的正常发展。在这个过程中,他作为"访问者",与战国时期的各种人物和事件进行交互。

  2. 元素的多样性 :战国时期的人物和事件可以被视为"元素",例如嬴政、乌廷芳、琴清、嫪毐等。每个元素都有其独特的属性和行为,项少龙需要与这些元素进行交互,以完成他的任务。

  3. 交互触发变化:项少龙与这些元素的交互,触发了一系列的变化。例如,他帮助嬴政成长,与乌廷芳和琴清建立了深厚的情感联系。这些交互不仅影响了项少龙自身,也影响了战国时期的历史进程。

  4. 历史轨迹的复杂性:尽管项少龙试图改变历史,但他最终发现历史的轨迹非常复杂,无法轻易改变。这体现了访问者模式中,访问者对元素的操作可能会受到元素自身复杂性的限制。

访问者模式通过将操作(项少龙和战国时期任务和事件的交互)从对象结构(战国的历史轨迹)中分离出来,封装在访问者(项少龙)类中,使得可以在不修改对象结构的情况下为对象添加新的操作。这种模式特别适用于需要对对象结构中的元素执行多种操作的场景。

二、为什么用访问者模式

我们来通过上述例子来看看为什么要使用访问者呢,或者什么样的场景使用到了访问者:

  1. 扩展性强:访问者模式能够在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能。在《寻秦记》中,项少龙可以尝试不同的策略和方法来影响历史,而不需要改变历史本身的结构。

  2. 集中管理复杂逻辑:访问者模式将对各个元素的一组操作集中在一个访问者类当中。项少龙的行动和决策都围绕着他的目标展开,使得他的行为更加有条理和系统化。

  3. 解耦数据结构和操作:在《寻秦记》中,项少龙作为访问者,与战国时期的各种人物和事件(元素)进行交互,而不需要改变这些元素本身的结构。这使得项少龙可以灵活地尝试不同的策略,而不会对历史结构本身造成不可逆的影响。

  4. 支持多种操作:访问者模式允许在不修改对象结构的情况下,为对象结构中的元素添加新的操作。项少龙可以尝试多种方法来影响历史,例如通过政治手段、军事手段或情感手段,而不需要改变历史本身的结构。

  5. 对象结构比较稳定,但经常需要在此对象结构上定义新的操作

  6. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类

三、访问者模式示例

下面我们拿项少龙的经历用代码带输出示例

  1. 定义元素接口(各种任务或者事件的统一行为,必须接受访问者)(Element)
java 复制代码
public interface Element {
    void accept(Visitor visitor);
}

2.实现具体元素类**(具体的事件或者人物,比如嬴政**)(ConcreteElement)

java 复制代码
public class YingZheng implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public void growWithXiangShaolong() {
        System.out.println("嬴政在项少龙的帮助下成长为一代帝王。");
    }
}

public class WuTingFang implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public void developRelationshipWithXiangShaolong() {
        System.out.println("乌廷芳与项少龙建立了深厚的情感联系。");
    }
}

public class LaoAi implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public void confrontXiangShaolong() {
        System.out.println("嫪毐与项少龙发生冲突。");
    }
}

3、定义访问者接口(访问者的统一行为)(Visitor)

java 复制代码
public interface Visitor {
    void visit(YingZheng yingZheng);
    void visit(WuTingFang wuTingFang);
    void visit(LaoAi laoAi);
}
  1. 实现具体访问者类(主角项少龙)(ConcreteVisitor)
java 复制代码
public class XiangShaolongVisitor implements Visitor {
    @Override
    public void visit(YingZheng yingZheng) {
        yingZheng.growWithXiangShaolong();
    }

    @Override
    public void visit(WuTingFang wuTingFang) {
        wuTingFang.developRelationshipWithXiangShaolong();
    }

    @Override
    public void visit(LaoAi laoAi) {
        laoAi.confrontXiangShaolong();
    }
}

5、场景复现(穿越大戏开始)

java 复制代码
public class Main {
    public static void main(String[] args) {
        // 创建具体元素对象
        Element yingZheng = new YingZheng();
        Element wuTingFang = new WuTingFang();
        Element laoAi = new LaoAi();

        // 创建具体访问者对象
        Visitor xiangShaolong = new XiangShaolongVisitor();

        // 执行操作
        yingZheng.accept(xiangShaolong);
        wuTingFang.accept(xiangShaolong);
        laoAi.accept(xiangShaolong);
    }
}

//输出
嬴政在项少龙的帮助下成长为一代帝王。
乌廷芳与项少龙建立了深厚的情感联系。
嫪毐与项少龙发生冲突。

通过这个代码示例,我们可以清晰地看到访问者模式的核心优势。访问者模式通过将操作从对象结构中分离出来,封装在访问者类中,使得可以在不修改对象结构的情况下为对象添加新的操作。这种模式特别适用于需要对对象结构中的元素执行多种操作的场景,例如项少龙在战国时期与不同角色的交互。

相关推荐
xcl09252 小时前
北京24小时自助健身房系统软件开发实战:从架构到部署全流程指南
java·spring boot·架构
一 乐4 小时前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
卓怡学长4 小时前
w214基于jsp知道特产网
java·intellij-idea
步行cgn5 小时前
Spring 注解使用详解
java·spring
一条小小yu5 小时前
Spring IoC的理解
java·后端·spring
落魄实习生5 小时前
Agent Scope Java 2.x 系列【7】工具使用
java·开发语言·ai
旺仔学长 哈哈5 小时前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
自强的小白7 小时前
核心功能(Service接口)
java·mybatis
乌暮8 小时前
深入理解 Java 泛型:把「万能盒子」用对、用稳
java·开发语言·后端·学习