zoukankan      html  css  js  c++  java
  • 访问者模式-Visitor

    访问者模式:表示作用于某对象结构的个元素的操作.它使你在不改变各元素的类的前提下定义作用于这些元素的新操作.

    访问者模式的适用场景:有比较稳定的数据结构,又有易于变化的算法的话,使用反复问这模式就是比较合适的,因为访问者模式使得算法操作的增加变得容易.

    访问者模式的优缺点:

    • 优点:增加新的操作容易,因为增加新的操作就意味着增加一个新的访问者.访问者模式将有关的行为集中到一个访问者对象中.
    • 缺点:访问者模式使得增加新的数据结构变得苦难了.

    访问者模式结构图:

    代码实现:

     1 package com.cgj.pattern.visitor;
     2 
     3 /**
     4  * Visitor接口
     5  */
     6 public interface Action {
     7 
     8     // 得到男人结论或反应
     9     public abstract void getManConclusion(Man concreteElement);
    10     
    11     // 得到女人的结论或反应
    12     public abstract void getWomanConclusion(Woman concreteElement);
    13 }
     1 package com.cgj.pattern.visitor;
     2 
     3 /**
     4  * Element接口:定义一个访问的方法,它以一个访问者为参数
     5  */
     6 public interface Person {
     7 
     8     // 他是用来获得Visitor对象的
     9     public abstract void accept(Action visitor);
    10 }
     1 package com.cgj.pattern.visitor;
     2 
     3 /**
     4  * 具体的Element类
     5  */
     6 public class Man implements Person {
     7 
     8     // visitor给出访问的结果
     9     @Override
    10     public void accept(Action visitor) {
    11         visitor.getManConclusion(this);
    12     }
    13 
    14 }
     1 package com.cgj.pattern.visitor;
     2 
     3 /**
     4  * 具体的Element类
     5  */
     6 public class Woman implements Person {
     7 
     8     // visitor给出访问的结果
     9     @Override
    10     public void accept(Action visitor) {
    11         visitor.getWomanConclusion(this);
    12     }
    13 
    14 }
     1 package com.cgj.pattern.visitor;
     2 
     3 /**
     4  * 具体的访问者,实现每个由Visitor声明的操作.
     5  * 每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类.
     6  */
     7 public class Success implements Action {
     8 
     9     @Override
    10     public void getManConclusion(Man concreteElement) {
    11         System.out.println("男人成功时,背后多半有一个伟大的女人.");
    12 
    13     }
    14 
    15     @Override
    16     public void getWomanConclusion(Woman concreteElement) {
    17         System.out.println("女人成功时,背后大多有一个不成功的男人.");
    18 
    19     }
    20 
    21 }
     1 package com.cgj.pattern.visitor;
     2 
     3 /**
     4  * 具体的访问者,实现每个由Visitor声明的操作.
     5  * 每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类.
     6  */
     7 public class Failing implements Action {
     8 
     9     @Override
    10     public void getManConclusion(Man concreteElement) {
    11         System.out.println("男人失败时,闷头喝酒谁也不用劝.");
    12 
    13     }
    14 
    15     @Override
    16     public void getWomanConclusion(Woman concreteElement) {
    17         System.out.println("女人失败时,眼泪汪汪,谁也劝不了.");
    18 
    19     }
    20 
    21 }
     1 package com.cgj.pattern.visitor;
     2 
     3 /**
     4  * 具体的访问者,实现每个由Visitor声明的操作.
     5  * 每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类.
     6  */
     7 public class Amativeness implements Action {
     8 
     9     @Override
    10     public void getManConclusion(Man concreteElement) {
    11         System.out.println("男人恋爱时,凡是不懂也要装懂.");
    12 
    13     }
    14 
    15     @Override
    16     public void getWomanConclusion(Woman concreteElement) {
    17         System.out.println("女人恋爱时,遇事懂也装作不懂.");
    18 
    19     }
    20 
    21 }
     1 package com.cgj.pattern.visitor;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 
     6 /**
     7  * 能枚举它的元素,可以提供一个高层的接口以允许访问者访问他的元素.
     8  */
     9 public class ObjectStructure {
    10 
    11     private List<Person> elements = new ArrayList<Person>();
    12 
    13     public boolean add(Person element) {
    14         return elements.add(element);
    15     }
    16 
    17     public boolean detach(Person element) {
    18         return elements.remove(element);
    19     }
    20 
    21     // 枚举所有元素
    22     public void display(Action visitor) {
    23         for (Person element : elements) {
    24             element.accept(visitor);
    25         }
    26     }
    27 }
     1 package com.cgj.pattern.visitor;
     2 
     3 /**
     4  * 首先在display函数中将具体的状态传递给Man类完成第一次分派,
     5  * 然后Man调用作为参数的状态类中的getManConslusion函数同时将自身
     6  * 作为参数传递进去,这便完成了第二次分派.
     7  */
     8 public class Test {
     9 
    10     public static void main(String[] args) {
    11         ObjectStructure structure = new ObjectStructure();
    12 
    13         structure.add(new Man());
    14         structure.add(new Woman());
    15 
    16         System.out.println("成功时的反应");
    17         structure.display(new Success());
    18 
    19         System.out.println("失败时的反应");
    20         structure.display(new Failing());
    21 
    22         System.out.println("恋爱时的反应");
    23         structure.display(new Amativeness());
    24     }
    25 
    26 }

    (本随笔参考了程杰老师的<<大话设计模式>>)

  • 相关阅读:
    c++语言特性深究
    springmvc和springboot的差别
    c++11新的大特性
    C/C++编程笔记:C语言进制详解,二进制、八进制和十六进制!
    程序人生丨想学编程,大学什么样的专业能成为一名真正的程序员?
    C/C++编程笔记:C语言预处理命令是什么?不要以为你直接写#就行!
    盘点:中国“颜值+才华”的几位知名女程序员!如何看待女生当程序员?
    程序人生丨三种语言实现—用户登录界面随机验证码,源代码分享!
    自学编程,为何你始终不能学出效果?切记一定要避免这 8 大误区!
    第二批《中等职业学校专业教学标准(试行)》目录
  • 原文地址:https://www.cnblogs.com/LionheartCGJ/p/7078531.html
Copyright © 2011-2022 走看看