18-访问者模式
1.访问者模式
- 访问者模式基础代码,该代码主要实现的功能是:从PPT、Pdf和Word中提取文字;存在的问题是:违反了开闭原则,当需要添加压缩功能时,即根据不同的文件类型,使用不同的压缩算法来压缩文件(压缩PPT、Pdf和Word文件)。
public class Extractor {
// 将PPT转换为txt文本文件。
public void extract2txt(PPTFile pptFile) {
System.out.println("Extract PPT.");
}
// 将Pdf转换为txt文本文件。
public void extract2txt(PdfFile pdfFile) {
System.out.println("Extract PDF.");
}
// 将Word转换为txt文本文件。
public void extract2txt(WordFile wordFile) {
System.out.println("Extract Word.");
}
}
public abstract class ResourceFile {
protected String filePath;
public ResourceFile(String filePath) {
this.filePath = filePath;
}
public abstract void accept(Extractor extractor);
}
public class PdfFile extends ResourceFile {
public PdfFile(String filePath) {
super(filePath);
}
// 将Pdf文件转为文本文件。
@Override
public void accept(Extractor extractor) {
// 根据this类型决定调用的extract2txt函数。
extractor.extract2txt(this);
}
}
// PPTFile和WordFile类和PdfFile类类似,省略。
- 增加压缩功能后的代码,当增加压缩功能后,会修改很多的代码,违反了开闭原则。
// 将PPT、Pdf和Word文件转换为文本文件。
public class Extractor {
public void extract2txt(PPTFile pptFile) {
System.out.println("Extract PPT.");
}
public void extract2txt(PdfFile pdfFile) {
System.out.println("Extract PDF.");
}
public void extract2txt(WordFile wordFile) {
System.out.println("Extract Word.");
}
}
// 根据不同的文件类型选择不同的算法进行文件压缩。
public class Compressor {
public void compress(PPTFile pptFile) {
System.out.println("Compress PPT.");
}
public void compress(PdfFile pdfFile) {
System.out.println("Compress Pdf.");
}
public void compress(WordFile wordFile) {
System.out.println("Compress Word.");
}
}
public abstract class ResourceFile {
protected String filePath;
public ResourceFile(String filePath) {
this.filePath = filePath;
}
// 文件转换为文本文件。
public abstract void accept(Extractor extractor);
// 压缩文件。
public abstract void accept(Compressor compressor);
}
public class PdfFile extends ResourceFile {
public PdfFile(String filePath) {
super(filePath);
}
// 将Pdf转换为文本文件。
@Override
public void accept(Extractor extractor) {
extractor.extract2txt(this);
}
// 压缩Pdf文件。
@Override
public void accept(Compressor compressor) {
compressor.compress(this);
}
}
// PPTFile和WordFile类和PdfFile类类似,省略。
- 访问者模式完整代码,通过增加Visitor接口来提高代码的扩展性。
// 访问接口。
public interface Visitor {
void visit(PdfFile pdfFile);
void visit(PPTFile pptFile);
void visit(WordFile wordFile);
}
public class Compressor implements Visitor {
@Override
public void visit(PdfFile pdfFile) {
System.out.println("Compress Pdf.");
}
@Override
public void visit(PPTFile pptFile) {
System.out.println("Compress PPT.");
}
@Override
public void visit(WordFile wordFile) {
System.out.println("Compress Word.");
}
}
public class Extractor implements Visitor {
@Override
public void visit(PdfFile pdfFile) {
System.out.println("Extract PDF.");
}
@Override
public void visit(PPTFile pptFile) {
System.out.println("Extract PPT.");
}
@Override
public void visit(WordFile wordFile) {
System.out.println("Extract Word.");
}
}
public abstract class ResourceFile {
protected String filePath;
public ResourceFile(String filePath) {
this.filePath = filePath;
}
public abstract void accept(Visitor visitor);
}
public class PdfFile extends ResourceFile {
public PdfFile(String filePath) {
super(filePath);
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
// 客户端代码
public static void main(String[] args) {
List<ResourceFile> resourceFileList = new ArrayList<>();
resourceFileList.add(new PdfFile(args[0]));
resourceFileList.add(new PPTFile(args[0]));
resourceFileList.add(new WordFile(args[0]));
// 将文件转换为文本文件
Extractor extractor = new Extractor();
for (ResourceFile resourceFile : resourceFileList) {
resourceFile.accept(extractor);
}
// 文件压缩
Compressor compressor = new Compressor();
for (ResourceFile resourceFile : resourceFileList) {
resourceFile.accept(compressor);
}
}
2.访问者模式总结
- <<设计模式:可复用面向对象软件的基础>>中对访问者模式的定义:允许一个或多个操作应用到一组对象上,解耦操作和对象本身。
- 访问者模式是22中经典设计模式中最难理解的,因为它难理解、难实现,引用它会导致代码可读性变差。所以访问者模式在实际软件开发中很少被使用。