封装一些作用域某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。
场景:平时在进行绩效考核的时候,CEO和CTO进行比较的东西是不同的。比如CEO只关心业绩,而CTO关心代码质量,项目成果。如果将考核写成一个方法进行维护,会有大量的逻辑判断,代码不美观且难以维护。
适用:
介绍:员工们就是参与考核的人。他们给供访问者查看内部属性的方法。
员工基类
public abstract class Staff {
    public String name;
    public int kpi; // 业绩指标
    public Staff(String name) {
        this.name = name;
        kpi = new Random().nextInt(10);
    }
    // 接受Visitor访问
    public abstract void accept(Visitor visitor);
}
开发
public class Engineer extends Staff {
    public Engineer(String name) {
        super(name);
    }
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
    public int getCodeLines() {
        return new Random().nextInt(10 * 10000);
    }
}
项目经理
public class Manager extends Staff {
    public Manager(String name) {
        super(name);
    }
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
    public int getProducts() {
        return new Random().nextInt(10);
    }
}
介绍:访问者需要实现对各种类型提供不同的访问方式,报表则是将员工信息录入。
访问者
public interface Visitor {
    // 访问工程师类型
    public void visit(Engineer engineer);
    // 访问经理类型
    public void visit(Manager manager);
}
CEO只关心KPI
public class CEO implements Visitor {
    @Override
    public void visit(Engineer engineer) {
        System.out.println("工程师:" + engineer.name + ",KPI:" + engineer.kpi);
    }
    @Override
    public void visit(Manager manager) {
        System.out.println("经理:" + manager.name + ",KPI:" + manager.kpi);
    }
}
CTO关心工作成绩
public class CTO implements Visitor {
    @Override
    public void visit(Engineer engineer) {
        System.out.println("工程师:" + engineer.name + ",代码量:" + engineer.getCodeLines());
    }
    @Override
    public void visit(Manager manager) {
        System.out.println("经理:" + manager.name + ",产品量:" + manager.getProducts());
    }
}
员工业绩报表
public class BusinessReport {
    List<Staff> staffs = new ArrayList<Staff>();
    public BusinessReport() {
        staffs.add(new Manager("李经理"));
        staffs.add(new Manager("陈经理"));
        staffs.add(new Engineer("java-李四"));
        staffs.add(new Engineer("python-张安"));
        staffs.add(new Engineer("C++-赵伟"));
    }
    /** * 展示业绩报表 */
    public void showReport(Visitor visitor) {
        for (Staff staff : staffs) {
            staff.accept(visitor);
        }
    }
}
// 构建报表
BusinessReport report = new BusinessReport();
System.out.println("=====CEO======");
report.showReport(new CEO());
System.out.println("=====CTO======");
report.showReport(new CTO());
输出
=====CEO====== 经理:李经理,KPI:5
经理:陈经理,KPI:3
工程师:java-李四,KPI:9
工程师:python-张安,KPI:2
工程师:C++-赵伟,KPI:3
=====CTO====== 经理:李经理,产品量:2
经理:陈经理,产品量:1
工程师:java-李四,代码量:95904
工程师:python-张安,代码量:46538
工程师:C++-赵伟,代码量:53854
总结:将一堆业务判断都分离了,代码层面十分简洁。不足也是会增加类的数量。
提枪策马乘胜追击04-21 20:01
代码小兵87207-15 12:10
杨晶珍05-11 14:54
杨晶珍05-12 17:30