博客
关于我
二十三种设计模式(第十五种)-----访问者模式(Visitor)
阅读量:507 次
发布时间:2019-03-07

本文共 2622 字,大约阅读时间需要 8 分钟。

访问者模式(Visitor) - 设计模式实践

模式概述

访问者模式是一种设计模式,旨在封装一些作用于某些数据结构中的各元素的操作。其核心思想是在不改变数据结构的情况下,为这些元素定义新的操作。这种模式能够将数据结构与数据操作分离,从而解决数据结构与操作的耦合性问题。

访问者模式的主要应用场景是:当需要对一个对象结构中的对象执行多种不同操作(这些操作彼此无关)时,且希望避免让这些操作"污染"对象的类。通过访问者模式,可以实现对这些操作的封装和扩展。

类图解析

访问者模式的核心类图包括以下几个关键角色:

  • Visitor:抽象访问者类,声明对具体元素的访问操作。
  • ConcreteVisitor:具体访问者类,实现 Visitor 中声明的操作。
  • ObjectStructure:对象结构类,负责管理和枚举对象结构中的元素。
  • Element:元素抽象类,定义一个 accept 方法接收访问者。
  • ConcreteElement:具体元素类,实现 accept 方法。
  • 通过这种方式,访问者模式实现了对数据操作的统一管理和扩展。

    实际应用场景

    以下是一个实际应用的示例:

    假设我们有一个 Person 类和其子类 ManWoman。每个子类都有一个方法 accept,用于接收一个操作对象。我们定义了一个抽象操作类 Action,其中包含两个抽象方法:getManResultgetWomanResult,用于分别处理男性和女性的测评结果。

    通过访问者模式,我们可以轻松地增加新的操作类型(如成功、失败等)而不需要修改现有的类结构。具体实现如下:

    // 定义抽象操作类public abstract class Action {    public abstract void getManResult(Man man);    public abstract void getWomanResult(Woman man);}// 定义抽象人类public abstract class Person {    public abstract void accept(Action action);}// 实现具体人类public class Man extends Person {    @Override    public void accept(Action action) {        action.getManResult(this);    }}public class Woman extends Person {    @Override    public void accept(Action action) {        action.getWomanResult(this);    }}// 实现具体的操作类(如成功、失败)public class Success extends Action {    @Override    public void getManResult(Man man) {        System.out.println("男人给的评价是成功");    }    @Override    public void getWomanResult(Woman man) {        System.out.println("女人给的评价是成功");    }}public class Fail extends Action {    @Override    public void getManResult(Man man) {        System.out.println("男人给的评价是失败");    }    @Override    public void getWomanResult(Woman man) {        System.out.println("女人给的评价是失败");    }}// 定义对象结构管理类public class ObjectStructure {    private List
    persons = new LinkedList<>(); public void attach(Person p) { persons.add(p); } public void detach(Person p) { persons.remove(p); } public void display(Action action) { for (Person person : persons) { person.accept(action); } }}// 客户端主程序public static void main(String[] args) { ObjectStructure objectStructure = new ObjectStructure(); objectStructure.attach(new Man()); objectStructure.attach(new Woman()); // 测试成功操作 Success success = new Success(); objectStructure.display(success); System.out.println("==================="); // 测试失败操作 Fail fail = new Fail(); objectStructure.display(fail);}

    双分派机制

    在上述实现中,双分派机制得到了很好的体现。双分派意味着不管操作的类型如何,系统都能正确地找到对应的方法进行执行。这意味着我们可以轻松地添加新的操作类型(如 Wait),而无需修改现有的类结构。只需定义一个新的 Action 子类,并在客户端进行调用即可。

    这种设计方式的优势在于,既保持了系统的灵活性,又避免了类之间的紧耦合,使得系统更容易进行扩展和维护。

    如果需要进一步了解访问者模式,可以参考相关技术文档或教学资源。

    转载地址:http://hlbcz.baihongyu.com/

    你可能感兴趣的文章
    TCP基本入门-简单认识一下什么是TCP
    查看>>
    tableviewcell 中使用autolayout自适应高度
    查看>>
    Symbolic Aggregate approXimation(SAX,符号聚合近似)介绍-ChatGPT4o作答
    查看>>
    Orcale表被锁
    查看>>
    svn访问报错500
    查看>>
    sum(a.YYSR) over (partition by a.hy_dm) 不需要像group by那样需要分组函数。方便。
    查看>>
    ORCHARD 是什么?
    查看>>
    Struts2中使用Session的两种方法
    查看>>
    Stream API:filter、map和flatMap 的用法
    查看>>
    STM32工作笔记0032---编写跑马灯实验---寄存器版本
    查看>>
    ssm旅游信息管理系统的设计与实现bus56(程序+开题)
    查看>>
    order by rand()
    查看>>
    SSM(Spring+SpringMvc+Mybatis)整合开发笔记
    查看>>
    Orderer节点启动报错解决方案:Not bootstrapping because of 3 existing channels
    查看>>
    org.apache.axis2.AxisFault: org.apache.axis2.databinding.ADBException: Unexpected subelement profile
    查看>>
    sql查询中 查询字段数据类型 int 与 String 出现问题
    查看>>
    org.apache.commons.beanutils.BasicDynaBean cannot be cast to ...
    查看>>
    org.apache.dubbo.common.serialize.SerializationException: com.alibaba.fastjson2.JSONException: not s
    查看>>
    sqlserver学习笔记(三)—— 为数据库添加新的用户
    查看>>
    org.apache.http.conn.HttpHostConnectException: Connection to refused
    查看>>