访问者模式——公司层级结构图

来源:互联网 发布:简谱打谱软件overture 编辑:程序博客网 时间:2024/06/03 18:18

一模式定义

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

 

二模式举例

1模式分析

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


 

2访问者模式静态类图



 

3代码示例

3.1抽象员工一Staff

package com.demo.structure;import com.demo.visitor.IVisitor;/** * 抽象员工类 *  * @author *  */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;/** * 管理人员(手下有其他员工的人) *  * @author *  */public class Manager extends Staff {// 存储手下员工信息private final ArrayList<Staff> arrayList = new ArrayList<Staff>();// 构造方法public Manager(String no, String name, String position, float salary) {super(no, name, position, salary);}/** * 增加一个员工 */@Overridepublic void add(Staff staff) {this.arrayList.add(staff);}/** * 删除员工信息 */@Overridepublic 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;}// 接收访问者对象@Overridepublic 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;/** * 普通员工(真正干活的人) *  * @author *  */public class Employees extends Staff{// 构造方法public Employees(String no, String name, String position, float salary){super(no, name, position, salary);}/** * 添加员工信息 */@Overridepublic void add(Staff staff){return;}/** * 删除员工信息 */@Overridepublic Staff remove(String no){// 直接返回nullreturn 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;/** * 访问者接口 *  * @author *  */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;/** * 打印基本信息访问者 *  * @author *  */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;/** * 计算薪资访问者 *  * @author *  */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;/** * 计算薪资访问者具体实现 *  * @author *  */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;/** * 主应用程序 *  * @author *  */public class Client {/** * @param args */public static void main(String[] args) {// 公司CEOStaff boss = new Manager("1", "大老板", "CEO", 100000);/** * CEO手下有若干部门经理 */// 财务部经理Staff financeManager = new Manager("11", "张总", "财务部经理", 60000);// 人事部经理Staff personnelManager = new Manager("12", "王总", "人事部经理", 60000);// 技术部经理Staff technicalManager = new Manager("13", "陈总", "技术部经理", 60000);/** * 技术部门还有助理和若干主管 */// 技术部门助理Staff deptAssistant = new Manager("1301", "王助理", "部门助理", 20000);// 技术部门主管1Staff deptManager1 = new Manager("1302", "主管1", "技术主管", 30000);/** * 技术主管deptManager1 下面还有软件工程师(最终干活的人) */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);// 技术部门主管2Staff deptManager2 = new Manager("1303", "主管2", "技术主管", 30000);// 为技术部经理 添加:部门助理、技术主管1和技术主管2technicalManager.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定义对象结构的类很少改变,但经常需要在此结构中定义新的操作。

 

五访问者模式静态类图



 

原创粉丝点击