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

一模式定义

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

 

二模式举例

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);
	}

	/**
	 * 增加一个员工
	 */
	@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;

/**
 * 普通员工(真正干活的人)
 * 
 * @author
 * 
 */
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;

/**
 * 访问者接口
 * 
 * @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) {
		// 公司CEO
		Staff 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);
		// 技术部门主管1
		Staff 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);

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

 

五访问者模式静态类图



 

计算机网络期末复习题 201708-201801计算机网络复习指导发布-校考学生!!下载截止于12.5日晚上9点 2017-12-04 23:07 计算机网络复习指导-校内考试 §1.名词解释: 1. 计算机网络 2.网络体系结构 3.高速以太网 4.静态路由选择 5. 动态路由选择 6.子网掩码 8.动态主机配置协议 9.套接字 10.客户/服务器模型(C/S模型) 11.域名系统(DNS) 12.光纤分布式数据接口FDDI §2.简答题: 1.试谈你对网络安全的威胁和防病毒技术的认识。(线下教学课件) 2.简述物理层的四个特性。(线下教学课件) 3.计算机网络的组成(P2-P3) 4.计算机网络的功能(P3) 5.计算机网络标准化的相关组织(P4+线下教学课件) 6.计算机网络的性能指标(P8+线下教学课件) 7.简述你所知道的网络传输介质(P33-34) 8.物理层的四个特性(P34) 9.简述四种帧边界的划分方法(即组帧方法)。(P52-54+线下教学课件) 10.简述停止-等待流量控制(协议)。(P59+P62-P64+线下教学课件) 11.简述时分多路复用(P69+线下教学课件) 12.简述频分多路复用(P68+线下教学课件) 13.简述IPv4地址的分类(P122-123) 14.UDP数据报与IP分组的区别(P187) §3.论述题: 1.试说明数据链路层原语和协议的转换。(线下教学课件) 2.描述常规释放的过程,并画出其示意图。(线下教学课件) 3.奈奎斯特定理公式和香农定理公式的主要区别是什么? 4.试比较电路交换、报文交换和分组交换等三种数据传输方式。(P27-29) 5.谈谈你对差错控制方法的理解。(P54-58+线下教学课件) 6.谈谈域名解析过程(P225-226) 7.ARP和DNS是否有些相似?它们有何区别?(P227) 8.FTP的工作原理。(P228)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值