栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java使用访问者模式解决公司层级结构图问题详解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java使用访问者模式解决公司层级结构图问题详解

本文实例讲述了Java使用访问者模式解决公司层级结构图问题。分享给大家供大家参考,具体如下:

一. 模式定义

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

二. 模式举例

1 模式分析

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

2 访问者模式静态类图

3 代码示例

3.1 抽象员工一Staff

package com.demo.structure;
import com.demo.visitor.IVisitor;

public abstract class Staff {
  // 员工号
  protected String no;
  // 职工名字
  protected String name;
  // 职位
  protected String position;
  // 薪资
  protected float salary;
  // 私有属性 长度字符串
  private int length;
  // 构造方法
  public Staff(String no, String name, String position, float salary) {
    this.no = no;
    this.name = name;
    this.position = position;
    this.salary = salary;
    // 计算总字节长度
    this.length += (no == null || "".equals(no.trim())) ? 0
 : no.getBytes().length;
    this.length += (name == null || "".equals(name.trim())) ? 0 : name
 .getBytes().length;
    this.length += (position == null || "".equals(position.trim())) ? 0
 : position.getBytes().length;
    this.length += String.valueOf(salary).getBytes().length;
  }
  // 获得用户基本信息
  public void printUserbaseInfo() {
    System.out.println("-|" + this.no + " " + this.name + " "
 + this.position + " " + this.salary);
  }
  // 添加员工信息
  public abstract void add(Staff staff);
  // 删除员工
  public abstract Staff remove(String no);
  // 接收访问者对象
  public abstract void accept(IVisitor visitor);
  public String getNo() {
    return no;
  }
  public void setNo(String no) {
    this.no = no;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getPosition() {
    return position;
  }
  public void setPosition(String position) {
    this.position = position;
  }
  public float getSalary() {
    return salary;
  }
  public void setSalary(float salary) {
    this.salary = salary;
  }
}

3.2 管理者一Manager

package com.demo.structure;
import java.util.ArrayList;
import com.demo.visitor.IVisitor;

public class Manager extends Staff {
  // 存储手下员工信息
  private final ArrayList arrayList = new ArrayList();
  // 构造方法
  public Manager(String no, String name, String position, float salary) {
    super(no, name, position, salary);
  }
  
  @Override
  public void add(Staff staff) {
    this.arrayList.add(staff);
  }
  
  @Override
  public Staff remove(String no) {
    Staff staff = null;
    if (no != null && !"".equals(no.trim())) {
      for (int i = 0; i < this.arrayList.size(); i++) {
 if (this.arrayList.get(i) == null) {
   continue;
 }
 if (no.equals(this.arrayList.get(i).getNo())) {
   staff = this.arrayList.remove(i);
   break;
 }
      }
    }
    return staff;
  }
  // 接收访问者对象
  @Override
  public void accept(IVisitor visitor) {
    // 访问自身
    visitor.visit(this);
    // 遍历list列表中的各个元素对象,接收访问者对象
    for (int i = 0; i < this.arrayList.size(); i++) {
      if (this.arrayList.get(i) == null) {
 continue;
      }
      // 接收访问者对象
      this.arrayList.get(i).accept(visitor);
    }
  }
}

3.3 普通员工一Employees

package com.demo.structure;
import com.demo.visitor.IVisitor;

public class Employees extends Staff
{
  // 构造方法
  public Employees(String no, String name, String position, float salary)
  {
    super(no, name, position, salary);
  }
  
  @Override
  public void add(Staff staff)
  {
    return;
  }
  
  @Override
  public Staff remove(String no)
  {
    // 直接返回null
    return null;
  }
  // 接收访问者对象
  public void accept(IVisitor visitor)
  {
    visitor.visit(this);
  }
}

3.4 访问者接口一IVisitor

package com.demo.visitor;
import com.demo.structure.Employees;
import com.demo.structure.Manager;

public interface IVisitor {
  // 访问管理者
  public void visit(Manager manager);
  // 访问普通员工
  public void visit(Employees employees);
}

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

package com.demo.visitor;
import com.demo.structure.Employees;
import com.demo.structure.Manager;

public class PrintbaseInfoVisitor implements IVisitor {
  
  public void visit(Manager manager) {
    System.out.print("- 管理者:");
    manager.printUserbaseInfo();
  }
  
  public void visit(Employees employees) {
    System.out.print("- 一般员工:");
    employees.printUserbaseInfo();
  }
}

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

package com.demo.visitor;

public interface ISalaryVisitor extends IVisitor {
  // 统计管理者薪资情况
  public void printManagerTotalSalary();
  // 统计一般员工薪资情况
  public void printEmployeesTotalSalary();
  // 统计所有员工薪资情况
  public void printTotalSalary();
}

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

package com.demo.visitor;
import com.demo.structure.Employees;
import com.demo.structure.Manager;

public class SalaryVisitor implements ISalaryVisitor {
  // 管理者薪资总和
  private float managerSalary;
  // 普通员工薪资总和
  private float employeesSalary;
  public SalaryVisitor() {
    managerSalary = 0;
    employeesSalary = 0;
  }
  // 访问管理者
  public void visit(Manager manager) {
    managerSalary += manager.getSalary();
  }
  // 访问普通员工
  public void visit(Employees employees) {
    employeesSalary += employees.getSalary();
  }
  // 统计一般员工薪资情况
  public void printEmployeesTotalSalary() {
    System.out.println("一般员工薪资总和:" + employeesSalary);
  }
  // 统计管理者薪资情况
  public void printManagerTotalSalary() {
    System.out.println("管理者薪资总和:" + managerSalary);
  }
  // 统计所有员工薪资情况
  public void printTotalSalary() {
    System.out.println("员工薪资总和:" + (managerSalary + employeesSalary));
  }
}

3.8 客户端测试一Client

package com.demo;
import com.demo.structure.Employees;
import com.demo.structure.Manager;
import com.demo.structure.Staff;
import com.demo.visitor.PrintbaseInfoVisitor;
import com.demo.visitor.SalaryVisitor;

public class Client {
  
  public static void main(String[] args) {
    // 公司CEO
    Staff boss = new Manager("1", "大老板", "CEO", 100000);
    
    // 财务部经理
    Staff financeManager = new Manager("11", "张总", "财务部经理", 60000);
    // 人事部经理
    Staff personnelManager = new Manager("12", "王总", "人事部经理", 60000);
    // 技术部经理
    Staff technicalManager = new Manager("13", "陈总", "技术部经理", 60000);
    
    // 技术部门助理
    Staff deptAssistant = new Manager("1301", "王助理", "部门助理", 20000);
    // 技术部门主管1
    Staff deptManager1 = new Manager("1302", "主管1", "技术主管", 30000);
    
    Staff softwareEngineer1 = new Employees("1302001", "张三", "软件工程师", 5000);
    Staff softwareEngineer2 = new Employees("1302002", "李四", "软件工程师", 5500);
    Staff softwareEngineer3 = new Employees("1302003", "王五", "软件工程师", 4500);
    // 为技术主管1添加员工信息
    deptManager1.add(softwareEngineer1);
    deptManager1.add(softwareEngineer2);
    deptManager1.add(softwareEngineer3);
    // 技术部门主管2
    Staff deptManager2 = new Manager("1303", "主管2", "技术主管", 30000);
    // 为技术部经理 添加:部门助理、技术主管1和技术主管2
    technicalManager.add(deptAssistant);
    technicalManager.add(deptManager1);
    technicalManager.add(deptManager2);
    // 市场部经理
    Staff marketingManager = new Manager("14", "吴总", "市场部经理", 60000);
    // 为CEO 添加:财务部经理、人事部经理、技术部经理和市场部经理
    boss.add(financeManager);
    boss.add(personnelManager);
    boss.add(technicalManager);
    boss.add(marketingManager);
    // 打印CEO 信息
    // boss.printUserbaseInfo();
    // 打印CEO 手下员工信息
    boss.accept(new PrintbaseInfoVisitor());
    
    // 创建统计员工薪资访问者
    SalaryVisitor visitor = new SalaryVisitor();
    // 让大老板接受该访问者
    boss.accept(visitor);
    // 管理者薪资统计情况
    visitor.printManagerTotalSalary();
    // 一般员工薪资统计情况
    visitor.printEmployeesTotalSalary();
    // 所有员工薪资统计情况
    visitor.printTotalSalary();
  }
}

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 定义对象结构的类很少改变,但经常需要在此结构中定义新的操作。

五. 访问者模式静态类图

更多java相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/141127.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号