• “访问者模式”学习


      学习访问者模式,写下一些浅显的认识。

      访问者模式可以将一个数据结构(一个类)的自身结构与对这个数据结构(类)的操作进行一定的分离。而操作就交与访问者进行处理。

      访问者模式使用于结构比较稳定的类。

      //====================

      来实现应用访问者模式的一个小例子:

      首先需要一个节点接口,该接口用有一个accept方法,参数是一个访问者接口,因为该节点时要被访问的,这个方法的作用就是指派该节点被谁(也就是哪个visitor)来访问。而参数的类型是一个接口,因为访问者的具体类型是可以变化的,这样就可以对节点进行多种操作了。

      

    package visitor;
    
    public abstract class INode {
        abstract public void accept(IVisitor v);
    }

      

      再写一个访问者接口,其实就是对节点进行操作的接口。该接口中有一个visit方法,其作用是指明访问者应该去访问哪个具体的节点。参数不能设置为一个接口类型,因为在调用方法的时候是调用具体的方法。IVisitor类应该是一个结构稳定的。也就是说对于node来讲它的实现是有限的,固定的。

    package visitor;
    
    public abstract class IVisitor {
        public abstract void visit(NodeImpA a);
        public abstract void visit(NodeImpB b);
        
        // 在此处不能以接口作为参数传入,因为在调用的时候会根据具体的类进行方法调用
        // public abstract void visit(INode node);    
    }

      

       下面实现INode接口,在accep方法中调用了IVisitor的visit方法,该方法接受的参数是一个具体的Node(NodeImpA/NodeImpB),所以v就会来指派应该调用IVisitor的哪个具体的visit方法。

    package visitor;
    
    public class NodeImpA extends INode {
        
        public void accept(IVisitor v) {
            v.visit(this);
        }
        
        public String actionA(){
            return "NodeImpA has be visited";
        }
    }
    package visitor;
    
    public class NodeImpB extends INode {
    
        public void accept(IVisitor v) {
            v.visit(this);
        }
        
        public String actionA() {
            return "NodeImpB has be visited";
        }
    }

      

       实现IVisitor接口,IVisitor中参数的传递都是以具体的类型进行传递的,这样在NodeImpA或NodeImpB传递this的时候就可以判断需要调用什么visit方法了,

    package visitor;
    
    public class VisitorImpA extends IVisitor {
    
        @Override
        public void visit(NodeImpA a) {
            System.out.println("VisitorImpA :" + a.actionA());
        }
    
        @Override
        public void visit(NodeImpB b) {
            System.out.println("VisitorImpA :" + b.actionA());
        }
    }
    package visitor;
    
    public class VisitorImpB extends IVisitor {
    
        @Override
        public void visit(NodeImpA a) {
            System.out.println("VisitorImpB :" + a.actionA());
        }
    
        @Override
        public void visit(NodeImpB b) {
            System.out.println("VisitorImpB :" + b.actionA());
        }
    
    }

      

      该模式需要一个管理的类,可以遍历结构中的所有元素。

    package visitor;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class ObjectStructure {
        private List<INode> nodes = new ArrayList<INode>();
    
        public void add(INode node){
            nodes.add(node);
        }
        
        public void manager(IVisitor v){
            for(INode node : nodes){
                node.accept(v);
            }
        }
        
        public static void main(String[] args) {
            INode a = new NodeImpA();
            INode b = new NodeImpB();
            
            ObjectStructure manager = new ObjectStructure();
            manager.add(a);
            manager.add(b);
            
            IVisitor va = new VisitorImpA();
            IVisitor vb = new VisitorImpB();
            
            manager.manager(va);
            manager.manager(vb);
            
        }
    }

      

      

      若我们需要对节点进行更多的操作,可以增加一个实现IVisitor的具体类。而对节点不做改动。但是如果节点发生了变化,这样访问者模式就会难以对付。

    http://www.cnblogs.com/java-my-life/archive/2012/06/14/2545381.html

    http://v.youku.com/v_show/id_XNjU5NzAwMjIw.html

  • 相关阅读:
    AcWing 276. I-区域
    学习笔记:可持久化线段树(主席树):静态 + 动态
    NOIP2016提高组 天天爱跑步
    AcWing 195. 骑士精神
    标准文档流
    css 盒模型
    css 继承性和层叠性
    css 选择器
    css 引入方式
    html body中的标签2
  • 原文地址:https://www.cnblogs.com/xinyuyu/p/3638192.html
Copyright © 2020-2023  润新知