• 24访问者模式Visitor


    一、什么是访问者模式

      Visitor模式也叫访问者模式,是行为模式之一 ,它分离对象的数据和行为,使用Visitor模式, 可以不修改已有类的情况下,增加新的操作。

    二、访问者模式的应用示例

      比如有一个公园,有一到多个不同的组成部分;该公 园存在多个访问者:清洁工A负责打扫公园的A部分,清 洁工B负责打扫公园的B部分,公园的管理者负责检点各 项事务是否完成,上级领导可以视察公园等等。也就是 说,对于同一个公园,不同的访问者有不同的行为操 作,而且访问者的种类也可能需要根据时间的推移而变 化(行为的扩展性)。

       根据软件设计的开闭原则(对修改关闭,对扩展开 放),我们怎么样实现这种需求呢?

    三、访问者模式的结构

    四、访问者模式的角色和职责

      1) 访问者角色(Visitor): 为该对象结构中具体元素角色声明一个访问操作接口。该操作接 口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。 这样访问者就可以通过该元素角色的特定接口直接访问它。

       2) 具体访问者角色(Concrete Visitor): 实现每个由访问者角色(Visitor)声明的操作。

      3) 元素角色(Element): 定义一个Accept操作,它以一个访问者为参数。

      4) 具体元素角色(Concrete Element): 实现由元素角色提供的Accept操作。

      5) 对象结构角色(Object Structure): 这是使用访问者模式必备的角色。它要具备以下特征:能枚举 它的元素;可以提供一个高层的接口以允许该访问者访问它的元 素;可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序 集合。

    公园每一部分的抽象

    1 // 公园每一部分的抽象
    2 public interface ParkElement {
    3     //用来接纳访问者
    4     public void accept(Visitor visitor);
    5 }

    公园

     1 //公园
     2 public class Park implements ParkElement {
     3     private String name;
     4     private ParkA parkA;
     5     private ParkB parkB;
     6     
     7     public Park() {
     8         this.parkA = new ParkA();
     9         this.parkB = new ParkB();
    10         parkA.setName("A");
    11         parkB.setName("B");
    12     }
    13 
    14     public void accept(Visitor visitor) {
    15         visitor.visit(this);
    16         parkA.accept(visitor);
    17         parkB.accept(visitor);
    18         
    19     }
    20 
    21     public String getName() {
    22         return name;
    23     }
    24 
    25     public void setName(String name) {
    26         this.name = name;
    27     }
    28 }

    公园的A部分

     1 // 公园的A部分
     2 public class ParkA implements ParkElement {
     3     private String name;
     4 
     5     public String getName() {
     6         return name;
     7     }
     8 
     9     public void setName(String name) {
    10         this.name = name;
    11     }
    12 
    13     public void accept(Visitor visitor) {
    14         visitor.visit(this);
    15     }
    16 }

    公园的B部分

     1 // 公园的B部分
     2 public class ParkB implements ParkElement{
     3     private String name;
     4     
     5     public String getName() {
     6         return name;
     7     }
     8 
     9     public void setName(String name) {
    10         this.name = name;
    11     }
    12 
    13     public void accept(Visitor visitor) {
    14         visitor.visit(this);
    15     }
    16 }

    访问者

    1 // 访问者
    2 public interface Visitor {
    3     public void visit(Park park);
    4     public void visit(ParkA parkA);
    5     public void visit(ParkB parkB);
    6 }

    清洁工A,负责parkA的卫生情况

     1 // 清洁工A,负责parkA的卫生情况
     2 public class VisitorA implements Visitor {
     3 
     4     public void visit(Park park) {
     5 
     6     }
     7 
     8     public void visit(ParkA parkA) {
     9         System.out.println("清洁工A:完成公园" + parkA.getName()+ "的卫生");
    10     }
    11 
    12     public void visit(ParkB parkB) {
    13 
    14     }
    15 }

    清洁工B,负责公园B部分的卫生

     1 // 清洁工B,负责公园B部分的卫生
     2 public class VisitorB implements Visitor {
     3 
     4     public void visit(Park park) {
     5 
     6     }
     7 
     8     public void visit(ParkA parkA) {
     9 
    10     }
    11 
    12     public void visit(ParkB parkB) {
    13         System.out.println("清洁工B:完成公园" + parkB.getName()+"的卫生");
    14     }
    15 }

    管理员

     1 //管理员
     2 public class VisitorManager implements Visitor {
     3 
     4     public void visit(Park park) {
     5         System.out.println("管理员:负责" + park.getName() + "卫生检查");
     6     }
     7 
     8     public void visit(ParkA parkA) {
     9         System.out.println("管理员:负责公园"+ parkA.getName() +"部分卫生检查");
    10     }
    11 
    12     public void visit(ParkB parkB) {
    13         System.out.println("管理员:负责公园"+ parkB.getName() +"分部卫生检查");
    14     }
    15 }

    测试

     1 public class MainClass {
     2     public static void main(String[] args) {
     3         Park park = new Park();
     4         park.setName("越秀公园");
     5         VisitorA visitorA = new VisitorA();
     6         
     7         park.accept(visitorA);
     8         
     9         VisitorB visitorB = new VisitorB();
    10         park.accept(visitorB);
    11         
    12         VisitorManager visitorManager = new VisitorManager();
    13         park.accept(visitorManager);
    14     }
    15 }
  • 相关阅读:
    其他综合收益的会计处理
    公允价值变动损益与投资收益的区别是什么?
    公允价值变动损益属于什么科目
    交易性金融资产和其他权益工具投资的区别
    属于在某一时段内履行的履约义务的情形
    合同履约成本和合同取得成本
    linux find查找并拷贝 exec xargs区别[转载]
    centos 安装discuz
    批处理变量,扩展,及变量截取
    常用DDL
  • 原文地址:https://www.cnblogs.com/justdoitba/p/9035444.html
Copyright © 2020-2023  润新知