首页 > 其他分享 >设计模式-访问者模式

设计模式-访问者模式

时间:2024-07-04 19:41:55浏览次数:1  
标签:visitor void 模式 element result 设计模式 public 访问者

访问者模式

访问者模式(Visitor Pattern)是一种将数据结构与数据操作分离的设计模式,是指封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作,属于行为型模式。

访问者模式被称为最复杂的设计模式,但是使用率不高。不过,一旦你需要使用它时,那就真的需要了,也就是这种场景其他方案很难达成目标。

基本思想

针对系统中拥有固定类型的对象结构,在其内提供一个accept()方法用来接收访问者对象的访问。不同的访问者对同一元素的访问内容不同,使得相同的元素可以产生不同的数据结果。
accept()方法可以接收不同的访问者对象,然后在内部将自己(元素)转发到接收到的访问者对象的visit()方法内,访问者内部对应类型的visit()方法就会得到回调执行,对元素进行操作。
也就是通过两次动态分发(①对访问者的分发accept()方法②对元素的分发visit()方法),才最终将一个具体的元素传递到一个具体的访问者。
如此一来,就解耦了数据结构与操作,且数据操作不会改变元素状态。

适用场景

  • 数据结构稳定,作用于数据结构的操作经常发生变化的场景;
  • 需要数据结构与数据操作分离的场景;
  • 需要对不同数据类型进行操作,而不使用分支判断具体类型的场景

代码

抽象元素:

package com.caozz.demo2.visitor.general;

// 抽象元素
public interface IElement {
    void accept(IVisitor visitor);
}

具体元素A:

package com.caozz.demo2.visitor.general;

// 具体元素
public class ConcreteElementA implements IElement {

    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }

    public String operationA() {
        return this.getClass().getSimpleName();
    }

}

具体元素B:

package com.caozz.demo2.visitor.general;

import java.util.Random;

// 具体元素
public class ConcreteElementB implements IElement {

    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }

    public int operationB() {
        return new Random().nextInt(100);
    }
}

抽象访问者:

package com.caozz.demo2.visitor.general;

// 抽象访问者
public interface IVisitor {

    void visit(ConcreteElementA element);

    void visit(ConcreteElementB element);
}

具体访问者A:

package com.caozz.demo2.visitor.general;

// 具体访问者
public class ConcreteVisitorA implements IVisitor {

    public void visit(ConcreteElementA element) {
        String result = element.operationA();
        System.out.println("result from " + element.getClass().getSimpleName() + ": " + result);
    }

    public void visit(ConcreteElementB element) {
        int result = element.operationB();
        System.out.println("result from " + element.getClass().getSimpleName() + ": " + result);
    }
}

具体访问者B:

package com.caozz.demo2.visitor.general;

// 具体访问者
public class ConcreteVisitorB implements IVisitor {

    public void visit(ConcreteElementA element) {
        String result = element.operationA();
        System.out.println("result from " + element.getClass().getSimpleName() + ": " + result);
    }


    public void visit(ConcreteElementB element) {
        int result = element.operationB();
        System.out.println("result from " + element.getClass().getSimpleName() + ": " + result);
    }
}

结构对象:

package com.caozz.demo2.visitor.general;

import java.util.ArrayList;
import java.util.List;

// 结构对象
public class ObjectStructure {
    private List<IElement> list = new ArrayList<IElement>();

    {
        this.list.add(new ConcreteElementA());
        this.list.add(new ConcreteElementB());
    }

    public void accept(IVisitor visitor) {
        for (IElement element : this.list) {
            element.accept(visitor);
        }
    }
}

测试:

package com.caozz.demo2.visitor.general;

/**
 * Created by Caozz
 */
public class Test {

    public static void main(String[] args) {
        ObjectStructure collection = new ObjectStructure();
        System.out.println("ConcreteVisitorA handle elements:");
        IVisitor visitorA = new ConcreteVisitorA();
        collection.accept(visitorA);
        System.out.println("------------------------------------");
        System.out.println("ConcreteVisitorB handle elements:");
        IVisitor visitorB = new ConcreteVisitorB();
        collection.accept(visitorB);
    }

}

测试结果:

ConcreteVisitorA handle elements:
result from ConcreteElementA: ConcreteElementA
result from ConcreteElementB: 17
------------------------------------
ConcreteVisitorB handle elements:
result from ConcreteElementA: ConcreteElementA
result from ConcreteElementB: 28
欢迎大家留言,以便于后面的人更快解决问题!另外亦欢迎大家可以关注我的微信公众号,方便利用零碎时间互相交流。共勉!

标签:visitor,void,模式,element,result,设计模式,public,访问者
From: https://www.cnblogs.com/caozz/p/18284539/visitor

相关文章

  • 【设计模式(三)】创建型模式--单例模式
    创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是“将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。饿汉式类加载就会导致该单实例对象被创建/***饿汉式*静态变量创建类的对象*/publicclassSingleton{//......
  • 详解五种Docker容器的网络模式
    Docker网络设置了容器如何与其他容器和外部服务通信。为了获得网络访问,容器需要是Docker网络的一部分。容器可以通信的方式取决于它的网络连接。Docker提供了五种标准网络模式来执行核心网络功能:Bridge(桥接)Host(主机)Overlay(重叠)IPvLANMacvl......
  • STM32 低功耗模式 睡眠、停止和待机 详解
    STM32提供了三种低功耗模式,分别是睡眠模式(SleepMode)、停止模式(StopMode)和待机模式(StandbyMode),我们在做一些电池供电项目的时候,低功耗模式显得尤为重要。模式名称进入唤醒唤醒后位置对1.2V域时钟的影响对VDD域时钟的影响功耗睡眠模式WFI任意中断睡眠位置开始执行CPU/CLK......
  • 报名参课 | 解锁 Serverless+AI 新模式,拥有专属AIGC环境
    如今,Serverless被越来越多的企业所接受,并应用于业务实践中。科技的每一次进步都在更新着我们的工作模式,除了互联网企业最早“尝鲜”之外,传统企业也在探索大规模使用Serverless。越来越多人迈过了对Serverless技术的初级认知阶段,走向了落地实践。Serverless和AI大模型都是......
  • 设计模式实现思路介绍
    设计模式是在软件工程中用于解决特定问题的典型解决方案。它们是在多年的软件开发实践中总结出来的,并且因其重用性、通用性和高效性而被广泛接受。设计模式通常被分为三种主要类型:创建型、结构型和行为型。创建型设计模式创建型设计模式专注于如何创建对象,以确保系统在创......
  • flink提交yarn 集群模式失败
    flink版本1.14.6在通过./bin/flinkrun-application-tyarn-application模式提交到yarn时失败。报错信息:点击查看代码Causedby:java.lang.ClassCastException:cannotassigninstanceoforg.apache.kafka.clients.consumer.OffsetResetStrategytofieldorg.apache.......
  • C++单例模式、工厂模式、观察者模式等的实现和应用场景。
    设计模式是软件开发中常用的解决方案,它们提供了一些经过验证的方法来解决常见的设计问题。以下是单例模式、工厂模式和观察者模式在C++中的实现和应用场景的详细讲解。1.单例模式(SingletonPattern)概念单例模式确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。......
  • selenium14_POM设计模式
    Python+Selenium+Unittest+Git+Jenkins框架,POM设计模式1.common文件夹:二次封装原有方法的文件base.py;存放通过的文件,如:生成报告的文件2.pages文件夹:page元素的定位;调用前边的封装方法,或者继承,再次封装一些页面的操作方法:如输入用户名密码点击登陆等操作。(或者元素定位,操作......
  • 抽象工厂模式
    文章目录抽象工厂模式案例代码定义多个产品以及多个实现类定义抽象工厂以及多个的子类工厂客户端使用输出结果抽象工厂模式定义个抽象父类,抽象父类中定义一个抽象的创建对象的方法,然后由子类来创建一系列相关的产品或者依赖簇,不同于工厂方法适用于单个产品。案例......
  • 采用Java语言+开发工具 Idea+ scode数字化产科管理平台源码,产科管理新模式
    采用Java语言+开发工具Idea+scode数字化产科管理平台源码,产科管理新模式数字化产科管理系统是现代医疗信息化建设的重要组成部分,它利用现代信息技术手段,对孕产妇的孕期管理、分娩过程及产后康复等各个环节进行数字化、智能化管理,以提升医疗服务质量和效率;以下是对数字化......