行为型设计模式之访问者模式(Visitor)

设计模式之访问者模式

在讲解访问者模式之前,我们先来看一个例子:假设现阶段公司的技术部门要求员工汇总各自的基础信息,以及工作内容。
代码结构如下:

public class Visitor_01 {
    //员工抽象类
    abstract static class Employee{
        private String name;//名字
        private int salary;//薪水
        private String job;//工作内容

        public Employee(String name, int salary, String job) {
            this.name = name;
            this.salary = salary;
            this.job = job;
        }

        public void report(){
            String report = new StringBuilder()
                    .append("姓名:"+this.name)
                    .append("       薪水:"+this.salary)
                    .append("       工作:"+this.job)
                    .append(this.getOtherInfo())
                    .toString();
            System.out.println(report);
        }

        public abstract String getOtherInfo();
    }

    //管理层
    static class Leader extends Employee{
        public Leader(String name, int salary, String job) {
            super(name, salary, job);
        }

        @Override
        public String getOtherInfo() {
            return new StringBuilder().append("     其他:爱拍马屁!!!").toString();
        }
    }
    //普通员工
    static class CommonEmploee extends Employee{
        public CommonEmploee(String name, int salary, String job) {
            super(name, salary, job);
        }

        @Override
        public String getOtherInfo() {
            return new StringBuilder().append("     其他:技术研究!!!").toString();
        }
    }

    public static void main(String[] args) {
        List<Employee> employees = new ArrayList<>();
        employees.add(new Leader("张三",18000, "管理员工"));
        employees.add(new CommonEmploee("李四", 15000, "架构设计"));
        employees.add(new CommonEmploee("王五", 12000, "写业务逻辑"));
        for (Employee employee : employees) {
            employee.report();
        }
    }
}

这是一个最基础的,使用了模板方法的一个设计。这里的report()是一个模板方法,定义了所有员工报告格式的大致框架,但是作为领导和普通员工的区别来讲,报告的格式和内容会有一些区别。如果领导类和普通员工类都遵循这个模板方法的话,一旦改方法结构变化,就会影响到所有的子类,这不是我们想要看到的。我们期望的设计是,员工和领导的报告细节的变更互不影响。

在这个实例里,普通员工类和领导类都是属于被大老板访问的对象,这个时候大老板就是一个访问者,只是他访问的对象不一样而已,有可能是领导,有可能是普通员工。那我们作为下级员工来讲,必须是允许领导来访问的;但是大老板访问下级员工到底想要知道些什么呢,这就应该由大老板自己来决定才行,因为下属信息对大老板都是透明的。
下面修改下设计:

public class Visitor_02 {
    interface IVisitor{
        void visitor(Leader leader);
        void visitor(CommonEmploee commonEmploee);
    }

    static class Visitor implements IVisitor{
        @Override
        public void visitor(Leader leader) {
            String report = new StringBuilder()
                    .append("姓名:"+leader.getName())
                    .append("       薪水:"+leader.getSalary())
                    .append("       工作:"+leader.getJob())
                    .append("       其他:爱拍马屁")
                    .toString();
            System.out.println(report);
        }

        @Override
        public void visitor(CommonEmploee commonEmploee) {
            String report = new StringBuilder()
                    .append("姓名:"+commonEmploee.getName())
                    .append("       薪水:"+commonEmploee.getSalary())
                    .append("       工作:"+commonEmploee.getJob())
                    .append("       其他:技术研究")
                    .toString();
            System.out.println(report);
        }


    }
    //员工抽象类
    abstract static class Employee{
        private String name;//名字
        private int salary;//薪水
        private String job;//工作内容

        public Employee(String name, int salary, String job) {
            this.name = name;
            this.salary = salary;
            this.job = job;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getSalary() {
            return salary;
        }

        public void setSalary(int salary) {
            this.salary = salary;
        }

        public String getJob() {
            return job;
        }

        public void setJob(String job) {
            this.job = job;
        }

        public abstract void accept(IVisitor iVisitor);
    }

    //管理层
    static class Leader extends Employee{
        public Leader(String name, int salary, String job) {
            super(name, salary, job);
        }

        @Override
        public void accept(IVisitor iVisitor) {
            iVisitor.visitor(this);
        }
    }
    //普通员工
    static class CommonEmploee extends Employee{
        public CommonEmploee(String name, int salary, String job) {
            super(name, salary, job);
        }

        @Override
        public void accept(IVisitor iVisitor) {
            iVisitor.visitor(this);
        }
    }

    public static void main(String[] args) {
        List<Employee> employees = new ArrayList<>();
        employees.add(new Leader("张三",18000, "管理员工"));
        employees.add(new CommonEmploee("李四", 15000, "架构设计"));
        employees.add(new CommonEmploee("王五", 12000, "写业务逻辑"));
        Visitor visitor = new Visitor();
        for (Employee employee : employees) {
            employee.accept(visitor);
        }
    }
}

如上代码:

  1. 定义一个访问者接口,定义访问不同具体对象的方法;
  2. 定义一个抽象的类,提供一个接收访问者的抽象方法,由子类实现;
  3. 定义一个具体的访问者实现类,来访问具体的被访问者,并进行逻辑处理;
  4. 具体的被访问对象的像访问者暴露自己的所有信息。

以上就是访问者模式的基本设计代码以及思路,下面看看官方的访问者模式的定义:封装一些作用于某种数据结构中的各个元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新操作。

简单来讲,就是暴露自己信息或结构给访问者,让访问者自己来实现逻辑。这样逻辑的变更不会影响到自己内部的结构。
但是由于visitor方法接收到的都是具体的类实例,并不是面向接口编程,所以扩展性不好。

参考编译器:ASM动态生成字节码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值