zoukankan      html  css  js  c++  java
  • 图解设计模式-Visitor模式

    Visitor模式即访问者模式
    在数据结构中保存许多元素,我们会对这些元素进行处理,这时“处理”代码放在那里比较好?通常的做法是将它们放在表示数据结构中的类中。但是,如果“处理”有许多中那?这种情况下,没当增加一种处理时,我们就不得不去修改表示数据结构的类。
    Visitor模式中将数据结构与处理分离开。
     
    角色:
    Visitor访问者:负责对数据结构中的每个具体元素声明一个用于访问XXXX的visitor(XXXX)方法。visitor(XXXX)用于处理XXXX的方法,负责实现该方法的是ConcreteVisitor角色,本示例中由Visitor类扮演。
    ConcreteVisitor具体的访问者:负责实现Visitor角色所定义的接口ApI。它要实现所有的visitor(XXXX)方法,即实现如何处理每个ConcreteElement角色。在本示例中,有ListVisitor类扮演。
    Element元素:表示Visitor角色的访问对象。它声明了介绍访问者的accept方法,accept方法接受到的参数为Visitor角色,本示例中由Element类扮演。
    ConcreteElement具体元素:负责实现Element角色所定义的接口API。
    Constructure对象结构:负责处理Element角色的集合。ConcreteVisitor角色为每个Element角色都准备了处理方法。
     
    代码:
    public abstract class Visitor {
        public abstract void visitor(File file);
        public abstract void visitor(Directory directory);
    }
    public interface Element {
        public abstract void accept(Visitor visitor);
    }
    public abstract class Entry implements Element {
        public abstract String getName();
        public abstract int getSize();
        public Entry add(Entry entry) throws Exception {
            throw new Exception("add");
        }
    
        public Iterator iterator() throws Exception {
            throw new Exception("iterator");
        }
    
        @Override
        public String toString() {
            return getName() + "("+getSize()+")";
        }
    }
    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 this.name;
        }
    
        @Override
        public int getSize() {
            return this.size;
        }
    
        @Override
        public void accept(Visitor visitor) {
            visitor.visitor(this);
        }
    }
    public class Directory extends Entry {
        private String name;
        private ArrayList<Entry> dir = new ArrayList<>();
    
        public Directory(String name) {
            this.name = name;
        }
    
        @Override
        public String getName() {
            return this.name;
        }
    
        @Override
        public int getSize() {
            int size = 0;
            for(Entry entry:dir) {
                size +=entry.getSize();
            }
            return size;
        }
        public Entry add(Entry entry) {
            dir.add(entry);
            return this;
        }
    
        public Iterator iterator() {
            return dir.iterator();
        }
    
        @Override
        public void accept(Visitor visitor) {
            visitor.visitor(this);
        }
    }
    public class ListVisitor extends Visitor {
        private String currentDir = "";
    
        @Override
        public void visitor(File file) {
            System.out.println(currentDir + "/" +file.getName());
        }
    
        @Override
        public void visitor(Directory directory) {
            System.out.println(currentDir + "/" +directory.getName());
            String savedir = currentDir;
            currentDir = currentDir + "/" +directory.getName();
            Iterator iterator = directory.iterator();
            while(iterator.hasNext()) {
                Entry entry = (Entry) iterator.next();
                entry.accept(this);
            }
            currentDir = savedir;
        }
    }
    public class Main {
        public static void main(String[] args) {
            try {
                Directory rootDir = new Directory("root");
                Directory binDir = new Directory("bin");
                Directory tempDir = new Directory("temp");
                Directory userDir = new Directory("user");
                rootDir.add(binDir);
                rootDir.add(tempDir);
                rootDir.add(userDir);
                binDir.add(new File("vi",1000));
                binDir.add(new File("latex",2000));
                rootDir.accept(new ListVisitor());
    
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
    }
    执行结果:
    /root
    /root/bin
    /root/bin/vi
    /root/bin/latex
    /root/temp
    /root/us
    收藏文章数量从多到少与“把书读薄”是一个道理
  • 相关阅读:
    javaweb登录验证码的实现
    jQuery Ajax 简单的实现跨域请求
    Java Socket长连接示例代码
    Java socket长连接代码实现
    带日期的bean转为json(bean->JSON)
    函数迭代器、生成器、递归
    闭包函数和装饰器
    函数名称空间与作用域
    函数基础
    基本的文件操作
  • 原文地址:https://www.cnblogs.com/use-D/p/9615954.html
Copyright © 2011-2022 走看看