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

访问者模式

时间:2024-01-31 11:44:23浏览次数:41  
标签:void 模式 public 课程 访问者 codingCourse beanDefinition

  • 定义:封装作用于某数据结构(如List/Set/Map等)中的各元素操作
  • 补充定义:可以在不改变各元素类的前提下,定义作用于这些元素的操作
  • 类型:行为型
  • 适用场景:
    • 一个数据结构(如List/Set/Map等)包含很多类型对象
    • 数据结构与数据操作分离
  • 优点:增加新的操作很容易,即增加一个新的访问者
  • 缺点:
    • 增加新的数据结构很困难
    • 具体元素变更比较麻烦
  • 相关设计模式:
    • 访问者模式和迭代器模式:都是在某种数据结构上处理,访问者模式主要用于对保存在数据结构中的元素进行某种特定的处理,迭代器模式主要用于逐个遍历保存在数据结构中的元素,重点在于遍历。

Coding

public abstract class Course {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public abstract void accept(IVisitor visitor);
}
public class FreeCourse extends Course {

    @Override
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }
}
public class CodingCourse extends Course {
    private int price;

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

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

    void visit(FreeCourse freeCourse);

    void visit(CodingCourse codingCourse);
}
public class Visitor implements IVisitor {

    /**
     * 访问免费课程,打印所有免费课程名称
     *
     * @param freeCourse
     */
    @Override
    public void visit(FreeCourse freeCourse) {
        System.out.println("免费课程:" + freeCourse.getName());
    }

    /**
     * 访问实战课程,打印所有实战课程名称及价格
     *
     * @param codingCourse
     */
    @Override
    public void visit(CodingCourse codingCourse) {
        System.out.println("实战课程:" + codingCourse.getName() + " 价格:" + codingCourse.getPrice() + "元");
    }
}

 

UML

IMG_256

测试

public class Test {
    public static void main(String[] args) {
        List<Course> courseList = new ArrayList<Course>();

        FreeCourse freeCourse = new FreeCourse();
        freeCourse.setName("SpringMVC数据绑定");

        CodingCourse codingCourse = new CodingCourse();
        codingCourse.setName("Java设计模式");
        codingCourse.setPrice(299);

        courseList.add(freeCourse);
        courseList.add(codingCourse);

        for (Course course : courseList) {
            course.accept(new Visitor());
        }
    }
}
============输出=============
免费课程:SpringMVC数据绑定
实战课程:Java设计模式 价格:299元
  • 说明:这个模式也很简单,定义了一个免费课程类和实战课程类,都继承了课程抽象类,访问者接口中有两个visit方法,分别用于不同课程的访问,其实现类中就是对应课程的访问。它的核心是根据不同的visitor对相同的数据(都是Course)产生不同的操作行为

源码中的应用

  • 在日常中并不常用,如果遇到数据加载和数据分离的情况下,就可以考虑是否使用访问者模式
  • java.nio.file.FileVisitor:文件访问者,通过它去遍历文件树会比较方便,比如查找文件夹内符合一定条件的文件,或者按时间查看某一天创建的文件,它的实现就一个SimpleFileVisitor,如果里面的方法不能满足我们的要求的话,可以继承这个类,覆盖里面的方法,或者自己写一个FileVisitor的实现。
public interface FileVisitor<T> {

    FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs) throws IOException;
    
    FileVisitResult visitFile(T file, BasicFileAttributes attrs) throws IOException;
    
    FileVisitResult visitFileFailed(T file, IOException exc) throws IOException;
        
    FileVisitResult postVisitDirectory(T dir, IOException exc) throws IOException;
}
  • org.springframework.beans.factory.config.BeanDefinitionVisitor:Bean定义的访问者,定义Bean的各种属性,然后用里面的properties进行填充,这个类主要对Bean的各种数据进行分析把它们进行分解,比如下面这个visitBeanDefinition方法
public class BeanDefinitionVisitor {
    private StringValueResolver valueResolver;

    public BeanDefinitionVisitor(StringValueResolver valueResolver) {
        Assert.notNull(valueResolver, "StringValueResolver must not be null");
        this.valueResolver = valueResolver;
    }
    public void visitBeanDefinition(BeanDefinition beanDefinition) {
        this.visitParentName(beanDefinition);
        this.visitBeanClassName(beanDefinition);
        this.visitFactoryBeanName(beanDefinition);
        this.visitFactoryMethodName(beanDefinition);
        this.visitScope(beanDefinition);
        this.visitPropertyValues(beanDefinition.getPropertyValues());
        ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues();
        this.visitIndexedArgumentValues(cas.getIndexedArgumentValues());
        this.visitGenericArgumentValues(cas.getGenericArgumentValues());
    }
}

 

标签:void,模式,public,课程,访问者,codingCourse,beanDefinition
From: https://www.cnblogs.com/wangzhilei-src/p/17998899

相关文章

  • 使用IDEA打jar包三种方式 步骤(包含跳过测试模式)
    使用IDEA打jar包三种方式步骤(包含跳过测试模式)正文:方式一:网络最常见的打包方式。比较适用于普通项目打JAR包。方式二:比较适用于MAVEN项目打JAR包。方式三:maven界面。方式一:网络最常见的打包方式。比较适用于普通项目打JAR包。选中菜单栏中File–>ProjectStructure(文件–>项......
  • 设计模式一句话总结
    1.设计原则(SOLID原则)原则名字原则描述单一职责原则(S)功能只有一个开闭原则(O)开放扩展,关闭修改里氏替换原则(L)子类需要实现父类功能以保持兼容性接口隔离原则(I)不用的函数或者功能不要出现依赖倒置原则(D)细节依赖于抽象,约定优先迪米特法则只和朋友说话......
  • 双亲委派模式的优点
    一道面试题能不能自己写个类叫java.lang.System?答案:通常不可以,但可以采取另类方法达到这个需求。解释:为了不让我们写System类,类加载采用委托机制,这样可以保证爸爸们优先,爸爸们能找到的类,儿子就没有机会加载。而System类是Bootstrap加载器加载的,就算自己重写,也总是使用Java系统......
  • 设计模式相关介绍
    设计模式使用原则主要包括以下几点:单一职责原则:一个类只负责一项职责,即一个类应该只有一个职责,该职责由类的一个职责来定义。这样可以提高类的可维护性和可复用性。开闭原则:软件实体应当对扩展开放,对修改封闭。也就是说,软件的功能扩展应当通过增加新代码来实现,而不是通过修改已......
  • 关于SortableJS在handle模式下移动端无法拖拽的解决办法
    原因个人项目使用到了这个库,PC操作好好的,移动端一看不行,然后去官方github-issues查看搜mobile的issue,发现大家也会这样。找了一圈看了下,应该是handle(句柄)模式下,库没有做事件监听导致的。解决办法要么换个库,要么在移动端的时候,取消句柄模式即可。constwrapper:HTMLElement=......
  • csharp 发布订阅 设计模式
    event_learn\Program.csusingSystem;//定义一个发布者类,它有一个MyEvent事件publicclassPublisher{//声明一个事件,使用EventHandler委托类型publiceventEventHandlerMyEvent;//定义一个触发事件的方法protectedvirtualvoidOnMyEvent()......
  • 在K8S中,flannel有几种模式?
    在Kubernetes(简称K8S)中,Flannel作为常用的网络插件之一,为集群提供覆盖网络(OverlayNetwork)支持,帮助Pod间实现跨主机通信。Flannel支持多种后端网络模式来实现这一功能,主要包括:VXLAN模式:VXLAN是一种Layer2虚拟化技术,它通过在IP包内封装二层以太网帧来创建一个跨越三层网络的虚......
  • 责任链模式
    比如一个web请求,有一堆的过滤器需要处理(或不处理)这个请求,而这一堆接收此次请求的过滤器对象形成一条调用链,即为责任链模式定义:为请求创建一个接收此次请求对象的链类型:行为型适用场景:一个请求的处理需要多个对象当中的一个或几个协作处理优点:请求的发送者和接收者(请求的处......
  • vmware nat模式详解
    vmwarenat模式主机和虚拟机是怎么联系,怎么上网的?关于natnat主要解决虚拟机上外网问题,虚拟机通过nat服务将内网地址和主机的wan口地址进行转换当虚拟机需要上网的时候,nat就会将数据包nat转换,然后从主机的wan口出去,和vm8虚拟网卡无光,关闭vm8虚拟机还是可以上网,只是无法进行内网......
  • C语言设计模式精要
    在C语言中,设计模式是一种常见的方法,它可以帮助我们更好地设计和实现软件系统。设计模式是一种面向对象的设计模式,它可以帮助我们更好地组织和管理代码,提高代码的可读性和可维护性。在C语言中,设计模式主要包括以下几种:单例模式、工厂模式、观察者模式、策略模式、装饰模式等。单......