访问者模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了访问者模式相关的知识,希望对你有一定的参考价值。

变量被声明时类型称为静态类型,变量引用的真实类型叫做实际类型。jvm根据对象类型进行方法的选择就是分派,根据发生时期分为静态分派和动态分派。静态分派发生于编译期,动态分派发生于运行期,即重载和重写。需要注意的是方法的调用是根据对象的真实类型而非静态类型。

一个方法所属的对象叫做方法的接收者,它与方法的参量统称为方法宗量。根据总量数量将面向对象语言分为单分派和多分派语言。java支持静态的多分派和动态的单分派。

java如若实现动态多分派怎么办?

1.传参然后在程序内进行类型检查,如:

 1 //模拟java.awt.Component类中的部分代码
 2 protected void processEvent(AWTEvent e){
 3       if(e instanceof (FocusEvent)e){
 4             processFocusEvent((FocusEvent)e);
 5       }else if(e instanceof (keyEvent)e){
 6             processkeyEvent((keyEvent)e);
 7       }else{
 8       ... 
 9       }
10 }

复杂易出错

2.访问者模式通用类图,画的不好将就看吧

技术分享

把数据结构和作用于数据结构上的操作之间的耦合解脱开,使得系统可以相对自由地演化。在实际系统中访问者模式可以用来处理跨越多个等级结构的树结构问题,这是访问者模式的优势。

□抽象访问者visitor:
抽象类或接口,声明访问者可以访问哪些元素,具体到程序中就是visit方法的参数定义哪些对象是可以被访问的。

1 public interface Visitor {
2     void visit(NodeA node);
3     void visit(NodeB node);
4 }

□具体访问者ConcreteVisitor:
它影响访问者访问到一个类后该怎么干,要做什么事情。

 1 //Visitor的一个实现A
 2 public class VisitorA implements Visitor{
 3     public void visit(NodeA nodea){
 4         //执行nodea的方法
 5         nodea.oprtiona();
 6     }
 7     public void visit(NodeB nodeb){
 8         //执行nodea的方法
 9         nodeb.oprtiona();
10     }
11 }
 1 //Visitor的一个实现B
 2 public class VisitorB implements Visitor{
 3     public void visit(NodeA nodea){
 4         //执行nodea的方法
 5         nodea.oprtiona();
 6     }
 7     public void visit(NodeB nodeb){
 8         //执行nodea的方法
 9         nodeb.oprtiona();
10     }
11 }

□抽象元素Node:

抽象类或接口,声明接收哪一类访问者访问,具体到程序中就是通过accept方法中的参数来定义。

1 public abstract class Node{
2     public abstract void accept(Visitor visitor);
3 }

□具体元素ConcreteNode:
实现accept方法,通常是visitor.visit(this)。同样给出两个:

1 public class NodeA extends Node{
2     @Override
3     public void accept(Visitor visitor) {
4         visitor.visit(this);
5     }
6     public void operationA(){
7         //NodeA的自定义方法
8     }    
9 }
1 public class NodeB extends Node{
2     @Override
3     public void accept(Visitor visitor) {
4         visitor.visit(this);
5     }
6     public void operationB(){
7         //NodeB的自定义方法
8     }    
9 }

□结构对象ObjectStructure:
元素生产者,一般容纳在多个不同类、不同的接口的容器,如List、Set、Map等。

 1 public class ObjectStructure{
 2     private Vector nodes;
 3     private Node node;
 4     public ObjectStructure{
 5         nodes = new Vector();
 6     }
 7     public void action(Visitor visitor){
 8         for (Enumeration e : nodes.elements();e.hasMoreElements()) {
 9             node =(Node)e.nextElement();
10             node.accept(visitor);
11         }
12     }
13     public void add(Node node){
14         nodes.addElement(node);
15     }16 }

客户端代码:

 1 public class Client{
 2     private static ObjectStructure aOject;
 3     private static Visitor visitor;
 4     public static void main(String[] args) {
 5         //创建结构对象
 6         aOject = new ObjectStructure();
 7         //增加节点a
 8         aOject.add(new NodeA());
 9         //增加节点b
10         aOject.add(new NodeB());
11         //创建访问者
12         visitor = new VisitorA();
13         //使用访问者访问结构
14         aOject.action(visitor);
15     }
16 }

但是访问者模式只适用于数据结构相对稳定的系统,它对于具体元素角色(本文中的NodeA、NodeB)的变更如增删改就显得笨重,不得不修改visitor以适应新需求,这样就违反开闭原则,所以应该慎重使用本模式。





以上是关于访问者模式的主要内容,如果未能解决你的问题,请参考以下文章

在不存在的片段上调用片段生命周期和 onCreate 的问题

尝试使用片段保存夜间模式状态

是否有在单个活动中处理多个片段的 Android 设计模式?

片段管理访问错误可见 return false

如何访问 MainActivity() 中的片段元素?

使用绑定从片段访问父活动的 UI 元素