`

访问者模式

 
阅读更多

一模式定义

访问者模式:是表示一个作用于某对象结构中各个元素的操作,它使用户可以在不改变各元素类的前提下定义作用于这些元素的新操作。

 

二模式举例

1模式分析

我们借用公司层级结构来说明这一模式。


 

2访问者模式静态类图



 

3代码示例

3.1抽象员工一Staff

Java代码  收藏代码
  1. package com.demo.structure;  
  2.   
  3. import com.demo.visitor.IVisitor;  
  4.   
  5. /** 
  6.  * 抽象员工类 
  7.  *  
  8.  * @author 
  9.  *  
  10.  */  
  11. public abstract class Staff {  
  12.     // 员工号  
  13.     protected String no;  
  14.     // 职工名字  
  15.     protected String name;  
  16.     // 职位  
  17.     protected String position;  
  18.     // 薪资  
  19.     protected float salary;  
  20.   
  21.     // 私有属性 长度字符串  
  22.     private int length;  
  23.   
  24.     // 构造方法  
  25.     public Staff(String no, String name, String position, float salary) {  
  26.         this.no = no;  
  27.         this.name = name;  
  28.         this.position = position;  
  29.         this.salary = salary;  
  30.   
  31.         // 计算总字节长度  
  32.         this.length += (no == null || "".equals(no.trim())) ? 0  
  33.                 : no.getBytes().length;  
  34.         this.length += (name == null || "".equals(name.trim())) ? 0 : name  
  35.                 .getBytes().length;  
  36.         this.length += (position == null || "".equals(position.trim())) ? 0  
  37.                 : position.getBytes().length;  
  38.         this.length += String.valueOf(salary).getBytes().length;  
  39.   
  40.     }  
  41.   
  42.     // 获得用户基本信息  
  43.     public void printUserBaseInfo() {  
  44.         System.out.println("-|" + this.no + " " + this.name + " "  
  45.                 + this.position + " " + this.salary);  
  46.     }  
  47.   
  48.     // 添加员工信息  
  49.     public abstract void add(Staff staff);  
  50.   
  51.     // 删除员工  
  52.     public abstract Staff remove(String no);  
  53.   
  54.     // 接收访问者对象  
  55.     public abstract void accept(IVisitor visitor);  
  56.   
  57.     public String getNo() {  
  58.         return no;  
  59.     }  
  60.   
  61.     public void setNo(String no) {  
  62.         this.no = no;  
  63.     }  
  64.   
  65.     public String getName() {  
  66.         return name;  
  67.     }  
  68.   
  69.     public void setName(String name) {  
  70.         this.name = name;  
  71.     }  
  72.   
  73.     public String getPosition() {  
  74.         return position;  
  75.     }  
  76.   
  77.     public void setPosition(String position) {  
  78.         this.position = position;  
  79.     }  
  80.   
  81.     public float getSalary() {  
  82.         return salary;  
  83.     }  
  84.   
  85.     public void setSalary(float salary) {  
  86.         this.salary = salary;  
  87.     }  
  88.   
  89. }  

3.2管理者一Manager

Java代码  收藏代码
  1. package com.demo.structure;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. import com.demo.visitor.IVisitor;  
  6.   
  7. /** 
  8.  * 管理人员(手下有其他员工的人) 
  9.  *  
  10.  * @author 
  11.  *  
  12.  */  
  13. public class Manager extends Staff {  
  14.   
  15.     // 存储手下员工信息  
  16.     private final ArrayList<Staff> arrayList = new ArrayList<Staff>();  
  17.   
  18.     // 构造方法  
  19.     public Manager(String no, String name, String position, float salary) {  
  20.         super(no, name, position, salary);  
  21.     }  
  22.   
  23.     /** 
  24.      * 增加一个员工 
  25.      */  
  26.     @Override  
  27.     public void add(Staff staff) {  
  28.         this.arrayList.add(staff);  
  29.     }  
  30.   
  31.     /** 
  32.      * 删除员工信息 
  33.      */  
  34.     @Override  
  35.     public Staff remove(String no) {  
  36.         Staff staff = null;  
  37.         if (no != null && !"".equals(no.trim())) {  
  38.             for (int i = 0; i < this.arrayList.size(); i++) {  
  39.                 if (this.arrayList.get(i) == null) {  
  40.                     continue;  
  41.                 }  
  42.   
  43.                 if (no.equals(this.arrayList.get(i).getNo())) {  
  44.                     staff = this.arrayList.remove(i);  
  45.                     break;  
  46.                 }  
  47.             }  
  48.         }  
  49.         return staff;  
  50.     }  
  51.   
  52.     // 接收访问者对象  
  53.     @Override  
  54.     public void accept(IVisitor visitor) {  
  55.   
  56.         // 访问自身  
  57.         visitor.visit(this);  
  58.         // 遍历list列表中的各个元素对象,接收访问者对象  
  59.         for (int i = 0; i < this.arrayList.size(); i++) {  
  60.             if (this.arrayList.get(i) == null) {  
  61.                 continue;  
  62.             }  
  63.   
  64.             // 接收访问者对象  
  65.             this.arrayList.get(i).accept(visitor);  
  66.         }  
  67.     }  
  68. }  

3.3普通员工一Employees

Java代码  收藏代码
  1. package com.demo.structure;  
  2.   
  3. import com.demo.visitor.IVisitor;  
  4.   
  5. /** 
  6.  * 普通员工(真正干活的人) 
  7.  *  
  8.  * @author 
  9.  *  
  10.  */  
  11. public class Employees extends Staff  
  12. {  
  13.     // 构造方法  
  14.     public Employees(String no, String name, String position, float salary)  
  15.     {  
  16.         super(no, name, position, salary);  
  17.     }  
  18.   
  19.     /** 
  20.      * 添加员工信息 
  21.      */  
  22.     @Override  
  23.     public void add(Staff staff)  
  24.     {  
  25.         return;  
  26.     }  
  27.   
  28.     /** 
  29.      * 删除员工信息 
  30.      */  
  31.     @Override  
  32.     public Staff remove(String no)  
  33.     {  
  34.         // 直接返回null  
  35.         return null;  
  36.     }  
  37.   
  38.     // 接收访问者对象  
  39.     public void accept(IVisitor visitor)  
  40.     {  
  41.         visitor.visit(this);  
  42.     }  
  43. }  

3.4访问者接口一IVisitor

Java代码  收藏代码
  1. package com.demo.visitor;  
  2.   
  3. import com.demo.structure.Employees;  
  4. import com.demo.structure.Manager;  
  5.   
  6. /** 
  7.  * 访问者接口 
  8.  *  
  9.  * @author 
  10.  *  
  11.  */  
  12. public interface IVisitor {  
  13.     // 访问管理者  
  14.     public void visit(Manager manager);  
  15.   
  16.     // 访问普通员工  
  17.     public void visit(Employees employees);  
  18. }  

3.5员工基本信息访问者一PrintBaseInfoVistor

Java代码  收藏代码
  1. package com.demo.visitor;  
  2.   
  3. import com.demo.structure.Employees;  
  4. import com.demo.structure.Manager;  
  5.   
  6. /** 
  7.  * 打印基本信息访问者 
  8.  *  
  9.  * @author 
  10.  *  
  11.  */  
  12. public class PrintBaseInfoVisitor implements IVisitor {  
  13.   
  14.     /** 
  15.      * 访问管理者对象 
  16.      */  
  17.     public void visit(Manager manager) {  
  18.         System.out.print("- 管理者:");  
  19.         manager.printUserBaseInfo();  
  20.     }  
  21.   
  22.     /** 
  23.      * 访问普通员工对象 
  24.      */  
  25.     public void visit(Employees employees) {  
  26.         System.out.print("- 一般员工:");  
  27.         employees.printUserBaseInfo();  
  28.     }  
  29.   
  30. }  

3.6创建统计员工薪资的访问者接口一ISalaryVistor

Java代码  收藏代码
  1. package com.demo.visitor;  
  2.   
  3. /** 
  4.  * 计算薪资访问者 
  5.  *  
  6.  * @author 
  7.  *  
  8.  */  
  9. public interface ISalaryVisitor extends IVisitor {  
  10.     // 统计管理者薪资情况  
  11.     public void printManagerTotalSalary();  
  12.   
  13.     // 统计一般员工薪资情况  
  14.     public void printEmployeesTotalSalary();  
  15.   
  16.     // 统计所有员工薪资情况  
  17.     public void printTotalSalary();  
  18.   
  19. }  

3.7统计员工薪资访问者实现一SalaryVistor

Java代码  收藏代码
  1. package com.demo.visitor;  
  2.   
  3. import com.demo.structure.Employees;  
  4. import com.demo.structure.Manager;  
  5.   
  6. /** 
  7.  * 计算薪资访问者具体实现 
  8.  *  
  9.  * @author 
  10.  *  
  11.  */  
  12.   
  13. public class SalaryVisitor implements ISalaryVisitor {  
  14.     // 管理者薪资总和  
  15.     private float managerSalary;  
  16.     // 普通员工薪资总和  
  17.     private float employeesSalary;  
  18.   
  19.     public SalaryVisitor() {  
  20.         managerSalary = 0;  
  21.         employeesSalary = 0;  
  22.     }  
  23.   
  24.     // 访问管理者  
  25.     public void visit(Manager manager) {  
  26.         managerSalary += manager.getSalary();  
  27.     }  
  28.   
  29.     // 访问普通员工  
  30.     public void visit(Employees employees) {  
  31.         employeesSalary += employees.getSalary();  
  32.     }  
  33.   
  34.     // 统计一般员工薪资情况  
  35.     public void printEmployeesTotalSalary() {  
  36.         System.out.println("一般员工薪资总和:" + employeesSalary);  
  37.     }  
  38.   
  39.     // 统计管理者薪资情况  
  40.     public void printManagerTotalSalary() {  
  41.         System.out.println("管理者薪资总和:" + managerSalary);  
  42.   
  43.     }  
  44.   
  45.     // 统计所有员工薪资情况  
  46.     public void printTotalSalary() {  
  47.         System.out.println("员工薪资总和:" + (managerSalary + employeesSalary));  
  48.   
  49.     }  
  50.   
  51. }  

3.8客户端测试一Client

Java代码  收藏代码
  1. package com.demo;  
  2.   
  3. import com.demo.structure.Employees;  
  4. import com.demo.structure.Manager;  
  5. import com.demo.structure.Staff;  
  6. import com.demo.visitor.PrintBaseInfoVisitor;  
  7. import com.demo.visitor.SalaryVisitor;  
  8.   
  9. /** 
  10.  * 主应用程序 
  11.  *  
  12.  * @author 
  13.  *  
  14.  */  
  15. public class Client {  
  16.   
  17.     /** 
  18.      * @param args 
  19.      */  
  20.     public static void main(String[] args) {  
  21.         // 公司CEO  
  22.         Staff boss = new Manager("1""大老板""CEO"100000);  
  23.         /** 
  24.          * CEO手下有若干部门经理 
  25.          */  
  26.         // 财务部经理  
  27.         Staff financeManager = new Manager("11""张总""财务部经理"60000);  
  28.   
  29.         // 人事部经理  
  30.         Staff personnelManager = new Manager("12""王总""人事部经理"60000);  
  31.   
  32.         // 技术部经理  
  33.         Staff technicalManager = new Manager("13""陈总""技术部经理"60000);  
  34.         /** 
  35.          * 技术部门还有助理和若干主管 
  36.          */  
  37.         // 技术部门助理  
  38.         Staff deptAssistant = new Manager("1301""王助理""部门助理"20000);  
  39.         // 技术部门主管1  
  40.         Staff deptManager1 = new Manager("1302""主管1""技术主管"30000);  
  41.         /** 
  42.          * 技术主管deptManager1 下面还有软件工程师(最终干活的人) 
  43.          */  
  44.         Staff softwareEngineer1 = new Employees("1302001""张三""软件工程师"5000);  
  45.         Staff softwareEngineer2 = new Employees("1302002""李四""软件工程师"5500);  
  46.         Staff softwareEngineer3 = new Employees("1302003""王五""软件工程师"4500);  
  47.         // 为技术主管1添加员工信息  
  48.         deptManager1.add(softwareEngineer1);  
  49.         deptManager1.add(softwareEngineer2);  
  50.         deptManager1.add(softwareEngineer3);  
  51.   
  52.         // 技术部门主管2  
  53.         Staff deptManager2 = new Manager("1303""主管2""技术主管"30000);  
  54.   
  55.         // 为技术部经理 添加:部门助理、技术主管1和技术主管2  
  56.         technicalManager.add(deptAssistant);  
  57.         technicalManager.add(deptManager1);  
  58.         technicalManager.add(deptManager2);  
  59.   
  60.         // 市场部经理  
  61.         Staff marketingManager = new Manager("14""吴总""市场部经理"60000);  
  62.   
  63.         // 为CEO 添加:财务部经理、人事部经理、技术部经理和市场部经理  
  64.         boss.add(financeManager);  
  65.         boss.add(personnelManager);  
  66.         boss.add(technicalManager);  
  67.         boss.add(marketingManager);  
  68.   
  69.         // 打印CEO 信息  
  70.         // boss.printUserBaseInfo();  
  71.         // 打印CEO 手下员工信息  
  72.         boss.accept(new PrintBaseInfoVisitor());  
  73.   
  74.         /** 
  75.          * 统计员工薪资情况 
  76.          */  
  77.         // 创建统计员工薪资访问者  
  78.         SalaryVisitor visitor = new SalaryVisitor();  
  79.         // 让大老板接受该访问者  
  80.         boss.accept(visitor);  
  81.         // 管理者薪资统计情况  
  82.         visitor.printManagerTotalSalary();  
  83.         // 一般员工薪资统计情况  
  84.         visitor.printEmployeesTotalSalary();  
  85.         // 所有员工薪资统计情况  
  86.         visitor.printTotalSalary();  
  87.     }  
  88. }  

4运行结果

- 管理者:-|1 大老板 CEO 100000.0

- 管理者:-|11 张总 财务部经理 60000.0

- 管理者:-|12 王总 人事部经理 60000.0

- 管理者:-|13 陈总 技术部经理 60000.0

- 管理者:-|1301 王助理 部门助理 20000.0

- 管理者:-|1302 主管1 技术主管 30000.0

- 一般员工:-|1302001 张三 软件工程师 5000.0

- 一般员工:-|1302002 李四 软件工程师 5500.0

- 一般员工:-|1302003 王五 软件工程师 4500.0

- 管理者:-|1303 主管2 技术主管 30000.0

- 管理者:-|14 吴总 市场部经理 60000.0

管理者薪资总和:420000.0

一般员工薪资总和:15000.0

员工薪资总和:435000.0

 

三该模式设计原则

1"开-闭"原则

2单一职责原则

 

四使用场合

1如果在一个对象结构中包含很多不同类型的对象,它们有不同的接口,而想对这些不同对象实施一些依赖于具体类的操作。

2需要对一个对象结构中的对象进行很多不同的并且不相关操作,而想避免让这些操作与这些对象的类关联起来。访问者模式使得可以将相关操作集中起来,单独定义在一个类中。

3当该对象结构被很多应用共享时,用访问者模式让每个应用仅包含需要用到的操作。

4定义对象结构的类很少改变,但经常需要在此结构中定义新的操作。

 

五访问者模式静态类图



 

分享到:
评论

相关推荐

    设计模式C++学习之访问者模式(Visitor)

    访问者模式(Visitor)是一种行为设计模式,它允许在不修改对象结构的前提下向对象结构中的元素添加新的操作。这种模式将算法与数据结构分离,使得算法可以独立于数据结构进行变化,增强了系统的可扩展性。 在C++中...

    访问者模式在实际开发中的Demo

    《访问者模式在实际开发中的应用深度解析》 访问者模式是设计模式中的一种行为模式,它在实际的软件开发中具有重要的应用价值。通过理解并掌握访问者模式,开发者可以更好地实现对象结构中元素的操作,同时保持元素...

    设计模式 访问者模式

    **访问者模式**是一种行为设计模式,它允许在不修改对象结构的情况下添加新的操作。这种模式主要用于处理具有复杂对象结构的情况,使得我们可以对结构中的每个元素执行特定操作,而无需暴露其内部实现。 访问者模式...

    访问者模式Demo

    **访问者模式**是一种设计模式,它在软件工程中用于在不修改对象结构的前提下,为对象添加新的操作或行为。这种模式将数据结构与数据操作分离,使得可以在不改变对象本身的情况下扩展其功能。访问者模式是行为设计...

    访问者模式代码

    访问者模式是一种设计模式,属于行为模式类别,其主要目的是在不修改对象结构的前提下,为对象结构中的元素提供新的操作。这种模式的核心思想是将数据结构与数据操作分离,使得增加新的操作变得容易,同时也避免了对...

    设计模式 - 访问者模式

    **访问者模式** 访问者模式(Visitor Pattern)是一种行为设计模式,它使你能在不修改对象结构的前提下向其添加新的操作。这种模式常用于处理具有相同接口或抽象类的对象结构,使得可以在不改变原有结构的基础上...

    访问者模式例子2

    访问者模式是一种设计模式,它在对象结构中定义了一个访问并操作其元素的接口。这种模式主要用于在不改变对象结构的前提下增加对象的功能。在“访问者模式例子2”中,我们将深入探讨如何利用该模式来扩展系统的行为...

    68丨访问者模式(上):手把手带你还原访问者模式诞生的思维过程1

    【访问者模式】是一种行为设计模式,其主要目的是在不修改已有对象结构的前提下,为对象增加新的操作。这种模式在23种经典设计模式中属于较为复杂的一种,因为它的理解和应用相对困难,可能导致代码可读性和可维护性...

    访问者模式例子

    访问者模式是一种设计模式,属于行为模式类别,它在软件工程中被用来分离对象结构与对这个结构进行操作的行为。这种模式的主要目的是使代码结构更加灵活,同时增加新的操作而无需修改现有对象结构。在“访问者模式”...

    设计模式的访问者模式的例子

    访问者模式是一种软件设计模式,它在对象结构中定义了一个访问者的接口,使得该访问者可以访问该结构中的每一个元素,同时不影响对象结构本身。这种模式的主要目的是将数据操作与数据结构分离,使得数据结构的变化...

    设计模式之访问者模式

    访问者模式是一种软件设计模式,它在对象结构中定义了一个访问者的接口,使得该访问者可以访问该结构中的每一个元素,同时不影响这些元素自身的行为。这种模式的主要目的是将数据操作和业务逻辑分离,使得数据结构...

    设计模式之访问者模式(Visitor)

    **访问者模式(Visitor)详解** 访问者模式是一种行为设计模式,它使你可以在不修改对象结构的情况下,为对象添加新的操作。这种模式的核心在于将数据结构与对这些数据的操作解耦,使得增加新的操作变得容易,同时...

    java设计模式之访问者模式

    访问者模式是一种软件设计模式,它允许在不改变对象结构的情况下,在对象的现有结构上增加新的操作。在Java中,这种模式尤其有用,因为它能够帮助我们保持类的封装性,同时提供了一种灵活的方式来扩展对象的功能。...

    设计模式-访问者模式(讲解及其实现代码)

    **访问者模式详解** 访问者模式是一种行为设计模式,它允许在不修改对象结构的情况下向对象添加新的操作。这种模式的核心思想是将数据结构与算法分离,使得算法可以在不改变对象结构的前提下增加对对象的操作。 在...

    Objective C 访问者模式设计源码

    访问者模式是一种软件设计模式,属于行为模式范畴,它的核心思想是将数据结构与数据操作分离,使得在不修改原有对象结构的情况下,可以为对象添加新的操作。这种模式常用于处理具有复杂对象结构且需要对这些对象进行...

    设计模式之访问者模式Java版本实现

    **访问者模式**是软件设计模式中的一种结构型模式,它允许在不修改对象结构的情况下,在对象上增加新的操作。这种模式将数据结构与数据操作分离,使得代码更易于维护和扩展。 在Java中实现访问者模式,通常包括以下...

    设计模式之访问者模式(Visitor Pattern)

    **访问者模式(Visitor Pattern)**是一种行为设计模式,它提供了一种在不修改对象结构的情况下增加新操作的方法。这种模式的主要思想是将数据结构与算法分离,使得算法可以在不改变对象结构的情况下独立变化。 在...

    uml 文档 访问者模式

    访问者模式是一种设计模式,主要用于在不修改原有类层次结构的基础上,增加新的操作或功能。在UML(统一建模语言)文档中,访问者模式通常用于表示对象结构中的类如何接受并处理来自访问者的访问请求。这个模式的...

Global site tag (gtag.js) - Google Analytics