十七、访问者模式——accpet后你就可以visit(this)了

本文讲解了访问者模式如何实现对文件列表的遍历,通过ResourceFile和Visitor接口,将数据抽取和压缩操作从文件结构中分离出来,提升代码灵活性。案例涉及ResourceFile抽象类和两种类型的子类,以及Extractor和Compressor两种不同的访问者实现。
摘要由CSDN通过智能技术生成


设计模式是面向问题、场景而总结产生的设计思路。是解决问题的套路。23 种经典的设计模式。它们又可以分为三大类:创建型、结构型、行为型。

行为型 包含了 观察者模式、模板模式、策略模式、职责链模式、状态模式、迭代器模式、 访问者模式、备忘录模式、命令模式、解释器模式、中介模式 总共11种模式。

访问者模式

访问者(Visitor)模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。
定义太抽象不好理解。
具体看一个案例:实现对文件列表的遍历,进行数据抽取和压缩行为。

1.定义ResourceFile

最核心是accpet(this),文件类定义了一个方法,允许vistor进来用visit方法访问this。

public abstract class ResourceFile {
    protected String path;

    public ResourceFile(String path) {
        this.path = path;
    }

    public abstract void accept(Vistor vistor);

    @Override
    public String toString() {
        return "ResourceFile{" +
                "path='" + path + '\'' +
                '}';
    }
}

public class ExcelFile extends ResourceFile {

    public ExcelFile(String path) {
        super(path);
    }

    @Override
    public void accept(Vistor vistor) {
        vistor.visit(this);
    }
}

public class XmlFile extends ResourceFile {

    public XmlFile(String path) {
        super(path);
    }

    @Override
    public void accept(Vistor vistor) {
        vistor.visit(this);
    }
}

2. 定义Visitor

Vistor 接口定义了访问方法,注意重载,有两个相同的accept方法。这是应用重载。这样是因为在传入参数的时候,是需要在编译期严格限定匹配类型的,因为要访问的对象子类必须明确。
Visitor 的子类有不同的访问器,并且对不同类型的文件进行不同的处理,依靠重载。

public interface Vistor {
    void visit(XmlFile file);
    void visit(ExcelFile file);
}

public class Extractor implements Vistor{
    @Override
    public void visit(XmlFile file) {
        System.out.println("Extrating XmlFile "+ file);
    }

    @Override
    public void visit(ExcelFile file) {
        System.out.println("Extrating ExcelFile "+ file);
    }
}

public class Compressor implements Vistor{
    @Override
    public void visit(XmlFile file) {
        System.out.println("Compressing XmlFile" + file);
    }

    @Override
    public void visit(ExcelFile file) {
        System.out.println("Compressing ExcelFile" + file);
    }
}

3. 组合在一起

public class Main {
    public static void main(String[] args) {
        List<ResourceFile> files = new ArrayList<>();
        Vistor extrator = new Extractor();
        Vistor comprossor = new Compressor();
        files.add(new XmlFile("abc.xml"));
        files.add(new ExcelFile("bcd.xls"));
        for(ResourceFile file:files) {
            file.accept(extrator);
        }
    }
}

运行结果

Extrating XmlFile ResourceFile{path='abc.xml'}
Extrating ExcelFile ResourceFile{path='bcd.xls'}

总结

一般来说,访问者模式针对的是一组类型不同的对象。不过,尽管这组对象的类型是不同的,但是,它们继承相同的父类(ResourceFile)或者实现相同的接口。在不同的应用场景下,我们需要对这组对象进行一系列不相关的业务操作(抽取文本、压缩等),我们使用访
问者模式,将对象与操作解耦,将这些业务操作抽离出来,定义在独立细分的访问者类(Extractor、Compressor)中。

Visitor 模式的应用场景有限,一般情况通过工厂方法也可以实现对应的工具类访问器的生成。

设计模式系列在github上有一个开源项目,主要是本系列博客的demo代码。https://github.com/forestnlp/designpattern
如果您对软件开发、机器学习、深度学习有兴趣请关注本博客,将持续推出Java、软件架构、深度学习相关专栏。
您的支持是对我最大的鼓励。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟空学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值