设计模式是面向问题、场景而总结产生的设计思路。是解决问题的套路。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、软件架构、深度学习相关专栏。
您的支持是对我最大的鼓励。