动力节点首页 全国咨询热线:400-8080-105

绑定手机号,登录
手机号

验证码

微信登录
手机号登录
手机号

验证码

30天自动登录
微信登录与注册
微信扫码登录与注册

扫码关注微信公众号完成登录与注册
手机号登录
首页 > 文章

访问者模式

03-27 21:21 599浏览
举报 T字号
  • 大字
  • 中字
  • 小字

1.介绍

封装一些作用域某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。

场景:平时在进行绩效考核的时候,CEO和CTO进行比较的东西是不同的。比如CEO只关心业绩,而CTO关心代码质量,项目成果。如果将考核写成一个方法进行维护,会有大量的逻辑判断,代码不美观且难以维护。

适用:

  • 一个对象结构包含很多类对象,它们有不同接口,而需要对这些对象实施一些依赖于其具体类的操作。
  • 需对一个对象结构中的对象进行很多不同且不相关的操作,但需要避免这些操作“污染”这些对象的类。
  • 定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。

2.苦逼的员工们

介绍:员工们就是参与考核的人。他们给供访问者查看内部属性的方法。

员工基类

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

3.大BOSS和报表

介绍:访问者需要实现对各种类型提供不同的访问方式,报表则是将员工信息录入。

访问者

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

4.开始考核

// 构建报表
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

总结:将一堆业务判断都分离了,代码层面十分简洁。不足也是会增加类的数量。

0人推荐
共同学习,写下你的评论
0条评论
我是码农
程序员我是码农

25篇文章贡献87343字

相关课程 更多>

作者相关文章更多>

推荐相关文章更多>

Java面试题及答案整理

代码小兵66904-21 20:01

6道经典算法面试题

杨晶珍05-12 16:39

简述Spring MVC的核心组件

代码小兵49806-11 16:26

SpringMVC 中的组件

代码小兵49806-11 16:28

Spring常见面试题

代码小兵92504-17 16:07

发评论

举报

0/150

取消