public abstract void printList(String prefix);
public void printList(){
printList("");
}
public Entry add(Entry entry) throws RuntimeException{
throw new RuntimeException();
}
public Iterator iterator() throws RuntimeException{
throw new RuntimeException();
}
@Override
public String toString() {
return getName()+"<"+getSize()+">";
}
}
package designMode.visitor;
import sun.reflect.generics.visitor.Visitor;
public class File extends Entry{
private String name;
private int size;
public File(String name, int size) {
this.name = name;
this.size = size;
}
@Override
public String getName() {
return name;
}
@Override
public int getSize() {
return size;
}
@Override
public void printList(String prefix) {
System.out.println(prefix+"/"+this);
}
public void accept(Visitor visitor){
visitor.visit(this);
}
}
package designMode.visitor;
import sun.reflect.generics.visitor.Visitor;
import java.util.ArrayList;
import java.util.Iterator;
public class Directory extends Entry {
String name;
ArrayList entrys = new ArrayList();
public Directory(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public int getSize() {
int size = 0;
Iterator it = entrys.iterator();
while (it.hasNext()){
size += ((Entry)it.next()).getSize();
}
return size;
}
@Override
public Entry add(Entry entry){
entrys.add(entry);
return this;
}
public Iterator iterator(){
return entrys.iterator();
}
@Override
public void printList(String prefix) {
System.out.println(prefix+"/"+this);
Iterator it = entrys.iterator();
Entry entry;
while (it.hasNext()){
entry = (Entry) it.next();
entry.printList(prefix+"/"+name);
}
}
public void accept(Visitor visitor){
visitor.visit(this);
}
}
package designMode.visitor;
public abstract class Visitor {
public abstract void visit(File file);
public abstract void visit(Directory directory);
}
package designMode.visitor;
import java.util.Iterator;
public class ListVisitor extends Visitor {
String currentDir = "";
@Override
public void visit(File file) {
System.out.println(currentDir+"/"+file);
}
@Override
public void visit(Directory directory) {
System.out.println(currentDir+"/"+directory);
String saveDir = currentDir;
currentDir +="/"+directory.getName();
Iterator it = directory.iterator();
while (it.hasNext()){
Entry entry = (Entry) it.next();
entry.accept(this);
}
currentDir=saveDir;
}
}
package designMode.visitor;
import java.util.ArrayList;
import java.util.Iterator;
public class FileVisitor extends Visitor {
String currentDir = "";
String suffix;
ArrayList files=new ArrayList();
public FileVisitor(String suffix){
this.suffix = suffix;
}
public void visit(File file) {
if(file.getName().endsWith(suffix)){
// System.out.println(currentDir+"/"+file);
files.add(currentDir+"/"+file);
}
}
public void visit(Directory directory) {
String saveDir=currentDir;
currentDir+=("/"+directory.getName());
Iterator it=directory.iterator();
while(it.hasNext()){
Entry entry=(Entry)it.next();
entry.accept(this);
}
currentDir=saveDir;
}
Iterator getFiles(){
return files.iterator();
}
}
package designMode.visitor;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
Directory root=new Directory("根目录");
Directory life=new Directory("我的生活");
File eat=new File("吃火锅.txt",100);
File sleep=new File("睡觉.html",100);
File study=new File("学习.txt",100);
life.add(eat);
life.add(sleep);
life.add(study);
Directory work=new Directory("我的工作");
File write=new File("写博客.doc",200);
File paper=new File("写论文.html",200);
File homework=new File("写家庭作业.docx",200);
work.add(write);
work.add(paper);
work.add(homework);
Directory relax=new Directory("我的休闲");
File music=new File("听听音乐.js",200);
File walk=new File("出去转转.psd",200);
relax.add(music);
relax.add(walk);
Directory read=new Directory("我的阅读");
File book=new File("学习书籍.psd",200);
File novel=new File("娱乐小说.txt",200);
read.add(book);
read.add(novel);
root.add(life);
root.add(work);
root.add(relax);
root.add(read);
root.accept(new ListVisitor());
System.out.println("========================");
FileVisitor visitor=new FileVisitor(".psd");
root.accept(visitor);
Iterator it = visitor.getFiles();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
![1157683-20180629170354003-2072968548.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTE1NzY4My8yMDE4MDYvMTE1NzY4My0yMDE4MDYyOTE3MDM1NDAwMy0yMDcyOTY4NTQ4LnBuZw?x-oss-process=image/format,png)
运行结果第一个和使用Composite模式的结果一样,第二个是实现另一种方式的访问,只访问文件后缀为某一特定的内容的文件,结果也是正确的,并且为了说明我们的访问还可以保存下来访问的结果,我们使用了ArrayList自带的迭代器将保存到ArrayList中的结果输出出来,我们当然也可以直接在遍历的时候就输出出来,这个看我们的使用要求了。因此可以看到在保证数据结构不发生变化的情况下,可以非常方便增加新的一种访问方法,只需要新增加一个访问类即可,但是如果我们数据结构发生变化之后,就需要修改继承自Visitor类的所有类了,这也违背了开闭原则,因此我们应该认真考虑,到底我们的数据结构是定死的还是经常变化的。没有任何一种设计模式是十全十美的,总是有所取舍,有所利弊,根据实际情况来选择才是最好的设计方法。
这里要说明一下双重分发机制,我们来看一下最核心的遍历逻辑,结合组合模式的时候我们已经分析过遍历方法,递归,大家觉得这次我们要怎么在数据结构外面进行遍历,肯定还要使用递归,可是数据结构中的数据在类的内部,怎么递归到内部呢,我们想到了间接递归,也就是双重分发。
public void printList(String prefix) {
System.out.println(prefix+"/"+this);
读者福利
分享一份自己整理好的Java面试手册,还有一些面试题pdf
不要停下自己学习的脚步
模式是十全十美的,总是有所取舍,有所利弊,根据实际情况来选择才是最好的设计方法。
这里要说明一下双重分发机制,我们来看一下最核心的遍历逻辑,结合组合模式的时候我们已经分析过遍历方法,递归,大家觉得这次我们要怎么在数据结构外面进行遍历,肯定还要使用递归,可是数据结构中的数据在类的内部,怎么递归到内部呢,我们想到了间接递归,也就是双重分发。
public void printList(String prefix) {
System.out.println(prefix+"/"+this);
# **读者福利**
分享一份自己整理好的Java面试手册,还有一些面试题pdf
**[领取方式;关注+点赞后,戳这里即可免费领取](https://gitee.com/vip204888/java-p7)**
**不要停下自己学习的脚步**
[外链图片转存中...(img-tpYpwXet-1628149945225)]
[外链图片转存中...(img-N3l1RGpy-1628149945228)]