design pattern · 2020-12-12 1

Java设计模式-访问者模式

一、概述

访问者模式(Visitor)是一种操作一组对象的操作,它的目的是不改变对象的定义,但允许新增不同的访问者,来定义新的操作。其主要目的是将数据结构与数据操作分离。

二、角色

  • 抽象访问者(Visitor):为每种具体的被访问者(ConcreteElement)声明一个访问操作

  • 具体访问者(ConcreteVisitor):实现对被访问者(ConcreteElement)的具体访问操作

  • 抽象被访问者(Element):通常有一个Accept方法,用来接收/引用一个抽象访问者对象

  • 具体被访问者对象(ConcreteElement):实现Accept抽象方法,通过传入的具体访问者参数、调用具体访问者对该对象的访问操作方法实现访问逻辑

三、访问者模式

1.抽象被访问者

public interface Employee {
    void accept(Department department);
}

2.具体被访问者对象

class ManagerEmployee implements Employee {

    private String name;

    private int timeSheet;

    private double wage;

    private int punishmentTime;

    public ManagerEmployee(String name, int timeSheet, double wage, int punishmentTime) {
        this.name = name;
        this.timeSheet = timeSheet;
        this.wage = wage;
        this.punishmentTime = punishmentTime;
    }

    @Override
    public void accept(Department department) {
        department.visit(this);
    }

    public int getTotalTimeSHeet() {
        return timeSheet * 22 - punishmentTime;
    }

    public double getTotalWage() {
        return wage - punishmentTime * 5;
    }

    public String getName() {
        return name;
    }
}
class GeneralEmployee implements Employee {

    private String name;

    private int timeSheet;

    private double wage;

    private int punishmentTime;

    public GeneralEmployee(String name, int timeSheet, double wage, int punishmentTime) {
        this.name = name;
        this.timeSheet = timeSheet;
        this.wage = wage;
        this.punishmentTime = punishmentTime;
    }

    @Override
    public void accept(Department department) {
        department.visit(this);
    }

    public int getTotalTimeSHeet() {
        return timeSheet * 22 - punishmentTime;
    }

    public double getTotalWage() {
        return wage - punishmentTime * 10;
    }

    public String getName() {
        return name;
    }
}

3.抽象访问者

public interface Department {

    void visit(ManagerEmployee managerEmployee);

    void visit(GeneralEmployee generalEmployee);
}

4.具体访问者

class FADepartment implements Department {

    @Override
    public void visit(ManagerEmployee managerEmployee) {
        double totalWage = managerEmployee.getTotalWage();
        System.out.println("管理者: " + managerEmployee.getName());
        System.out.println("实发工资: " + totalWage);
    }

    @Override
    public void visit(GeneralEmployee generalEmployee) {
        double totalWage = generalEmployee.getTotalWage();
        System.out.println("普通员工者: " + generalEmployee.getName());
        System.out.println("实发工资: " + totalWage);
    }
}
class HRDepartment implements Department {

    @Override
    public void visit(ManagerEmployee managerEmployee) {
        int totalTimeSHeet = managerEmployee.getTotalTimeSHeet();
        System.out.println("管理者: " + managerEmployee.getName());
        System.out.println("工作时长: " + totalTimeSHeet);
    }

    @Override
    public void visit(GeneralEmployee generalEmployee) {
        int totalTimeSHeet = generalEmployee.getTotalTimeSHeet();
        System.out.println("普通员工: " + generalEmployee.getName());
        System.out.println("工作时长: " + totalTimeSHeet);
    }
}

5.测试

@Test
public void testVisitor() {
    List<Employee> employees = new ArrayList<>();
    Employee emp1 = new ManagerEmployee("管理者A", 8, 20000, 10);
    Employee emp2 = new ManagerEmployee("管理者B", 8, 15000, 15);
    Employee emp3 = new GeneralEmployee("普通员工A", 8, 8000, 5);
    Employee emp4 = new GeneralEmployee("普通员工B", 8, 7000, 10);
    employees.add(emp1);
    employees.add(emp2);
    employees.add(emp3);
    employees.add(emp4);

    System.out.println("- - - 财务部门查看员工 - - -");
    FADepartment fa = new FADepartment();
    employees.forEach(e -> e.accept(fa));

    System.out.println("- - - 人力部门查看员工 - - -");
    HRDepartment hr = new HRDepartment();
    employees.forEach(e -> e.accept(hr));
}