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
    收藏文章数量从多到少与“把书读薄”是一个道理
  • 相关阅读:
    用的springboot+mybatis plus,报错bean无法实例化
    coding使用
    drop表后仍占表空间解决办法
    oracle从零开始学习笔记 三
    oracle从零开始学习笔记 二
    录制简单的自动化测试工具SlikMobile初体验
    appium 等待页面元素加载
    sdk 更新的时连接不上dl-ssl.google.com解决办法
    oracle从零开始学习笔记
    oracle: tochar(sysdate,'D')函数
  • 原文地址:https://www.cnblogs.com/use-D/p/9615954.html
Copyright © 2011-2022 走看看