• 访问者模式


    首先

    抽象员工

    public abstract class Employee{
        // 代表男性
        public final static int MALE = 0;
        // 代表女性
        public final static int FEMALE = 1;
        // 有工资
        private String name;
        // 薪水
        private int salary;
        // 性别
        private int sex;
        // get/set
        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 int  getSex(){
            return sex;
        }
        public void setSex(int sex){
            this.sex = sex;
        }
        // 员工信息输出
        public final void report(){
            String info = "姓名" + this.name + "	";
            info = info + "性别" + this.sex + "	";
            info = info + "薪水" + this.salary + "	";
            info = info + this.getOtherinfo();
            System.out.println(info);
        }
        // 拼装
        protected abstract String getOtherinfo();
    }
    

    下面是普通员工

    public class CommonEmployee extends Employee{
        // 工作内容
        private String job;
        public String getJob(){
            return job;
        }
        public void setJob(String job){
            this.job = job;
        }
        protected String getOtherinfo(){
            return "工作: " + this.job + "	";
        }
    }
    

    管理层

    public class Manager extends Employee{
        // 职责
        private String performance;
        public String getPerformance(){
            return performance;
        }
        public void setPerformance(String performance){
            this.performance = performance;
        }
        protected String getOtherinfo(){
            return "业绩" + this.performance + "	";
        }
    }
    

    最后场景

    public class Client{
        public static void main(String[] args){
            for(Employee emp:mockEmployee()){
                emp.report();
            }
        }
        public static List mockEmployee(){
            List empList = new ArrayList();
            // 产生员工
            CommonEmployee zhangSan = new CommonEmployee();
            zangSan.setJon("编写程序");
            zangSan.setName("张三");
            zangSan.setSalary(1800);
            zangSan.setSex(Employee.MALE);
            empList.add(zangSan);
            // 产生员工
            CommonEmployee liSi = new CommonEmployee();
            liSi.setJob("美工");
            liSi.setName("李四");
            liSi.setSalary(1900);
            liSi.setSex(Employee.FEMALE);
            empList.add(liSi);
            // 产生经理
            Manage wangWu = new Manger();
            wangWu.setName("王五");
            wangWu.setPerformance("负值");
            wangWu.setSalary(18750);
            wangWu.setSex(Employee.MALE);
            empList.add(wangWu);
            return empList;
        }
    }
    

    改造如下

    先定义访问者接口

    public interface IVisitor{
        // 定义普通员工
        public void vsit(CommonEmployee commonEmployee);
        // 定义访问部门经理
        public void visit(Manager manager);
    }
    

    访问者实现

    public class Visitor implements IVisitor{
        // 访问普通员工,打印报表
        public void visit(CommonEmployee commonEmployee){
            System.out.println(this.getCommonEmployee(commonEmployee));
        }
        // 访问部门经理
        public void visit(Manager manager){
            System.out.println(this.getManagerinfo(manager));
        }
        // 组装基本信息
        private String getBasicinfo(Employee employee){
            String info = "姓名" + employee.getName() + "	";
            info = info + "性别" + (employee.getSex() == Employee.FEMALE?"女","男");
            info = info + "薪水" + employee.getSalary() + "	";
            return info;
        }
        // 组装普通员工信息
        private String getCommonEmployee(CommonEmployee commonEmployee){
            String basicinfo = this.getBasicinfo(commonEmployee);
            String otherinfo = "工作" + commonEmployee.getJob() + "	";
            return basicinfo + otherinfo;
        }
        
    }
    

    继续书写抽象员工类

    public abstract class Employee{
        public final static int MALE = 0;
        public final static int FEMALE = 1;
        // 工资
        private String name;
        // 薪水
        private int salary;
        // 性别
        private int sec;
        // get/set
        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 int getSex(){
            return sex;
        }
        public void setSex(int sex){
            this.sex = sex;
        }
        // 定义访问者访问
        public abstract void accept(IVisitor visitor);
    }
    

    普通员工

    public class CommonEmployee extends Employee{
        // 工作内容
        private String job;
        // 获得job
        public String getJon(){
            return job;
        }
        // 设置job
        public void setJob(String job){
            this.job = job;
        }
        // 允许访问者访问
        @Override
        public void accept(IVsitor visitor){
            visitor.visit(this);
        }
    }
    

    场景类

    public class Client{
        public static void main(String[] args){
            // 开始循环列表
            for(Employee emp:mockEmployee()){
                // 将访问者传入,此时accept将会调用visit方法,将this传入
                emp.accept(new Visitor());
            }
        }
        public static List mockEmployee(){
            List empList = new ArrayList();
            // 产生员工
            CommonEmployee zhangSan = new CommonEmployee();
            // 设置属性
            zhangSan.setJon("编写程序");
            zhangSan.setName("张三");
            zhangSan.setSalary(1800);
            zhangSan.setSex(Employee.MALE);
            empList.add(zhangSan);
            // 产生员工
            CommonEmployee liSi = new CommonEmployee();
            liSi.setJob("美工");
            liSi.setSalary("李四");
            liSi.setSalary(1900);
            liSi.setSex(Employee.FEMALE);
            // 入数组
            empList.add(liSi);
            // 产生经理
            Manager wangWu = new Manager();
            wangWu.setName("王五");
            wangWu.setPerformance("负数");
            wangWu.setSalary(18750);
            wangWu.setSex(Employee.MALE);
            empList.add(wangWu);
            return empList;
        }
    }
    

    扩展

    统计功能

    汇总和报表,经常使用统计功能。
    即,一堆计算公式,生产出一个报表。
    统计公式员工的工资总额

    // 定义抽象访问者
    public interface IVisitor{
        // 定义可以访问的普通员工
        public void visit(CommonEmployee commonEmployee);
        // 再次定义访问部门经理
        public void visit(Manager manager);
        // 统计员工工资总和
        public int getTotalSalary();
    }
    

    定义访问者

    // public class Visitor implements IVisitor{
        // 这里实现接口
    }
    

    最后编写场景类

    public class Client{
        public static void main(String[] args){
            // 定义一个访问者
            // 展示报表的访问者
            ISVisitor showVisitor = new Visitor();
            // 汇总报表的访问者
            ITotalVisitor totalVisitor = new TotalVisitor();
            // 遍历,其中mockEmployee是从持久层传来的数据
            for(Employee emp:mockEmployee()){
                // 对数据进行处理,
                // 代执行访问着的visit方法。由于数据是保存在emp的,所以需要将this传入
                emp.accept(showVisitor);
                emp.accept(totalVisitor);
            }
            System.out.println("");
        }
    }
    

    双分派

    单分派:处理一个操作根据请求着的名称和接受到的参数决定
    静态绑定,动态绑定,依据重载,覆写实现。
    栗子

    // 定义角色接口,实现类
    public interface Role{
        // 演员扮演的角色
    }
    public class KungFuRole implements Role{
        // 武功第一的角色
    }
    public class idiotRole implements Role{
        // 弱智角色
    }
    

    下面定义抽象演员

    public abstract class AbsActor{
        // 演员能够扮演的角色
        public void act(Role role){
            // 演员扮演的角色
        }
        // 扮演功夫戏
        public void act(KungFuRole role){
            // 扮演功夫戏
        }
    }
    
    // 青年演员,老年演员
    public class YoungActor extends AbsActor{
        // 年轻演员喜欢的功夫戏
        public void act(KungFuRole role){
        
        }
    }
    
    // 老年演员喜欢的功夫戏
    public class OldActor extends AbsActor{
        // 扮演功夫角色
        public void act(KungFuRole role){
            // 扮演功夫角色
        }
    }
    

    编写场景

    public class Client{
        public static void main(String[] args){
            // 定义一个演员
            AbsActor actor = new OldActor();
            // 定义一个角色
            Role role = new KungFuRole();
            // 开始演戏
            actor.act(role);
            actor.act(new KungFuRole());
        }
    }
    

    重载在编译期间决定要调用那个方法。
    静态绑定,是重写的时候就断定要绑定那个,例如定义年轻演员的时候,重写的act方法,此时为静态绑定了KungFuRole,
    动态绑定呢,act方法,只有在运行的时候才能判断是和那个绑定

    一个演员可以扮演多个角色,如何实现呢,使用访问者模式

    public interface Role{
        // 演员扮演的角色
        public void accept(AbstActor actor);
    }
    public class KungFuRole implements Role{
        // 角色
        public void accept(Abstract actor){
            actor.act(this);
        }
    }
    public class ldiotRole implements Role{
        // 弱智角色
        public void accept(AbsActor actor){
            actor.act(this);
        }
    }
    书写场景类
    public class Clicent{
        public static void main(String[] args){
            // 定义演员
            AbsActor actor = new OldActor();
            // 定义角色
            Role role = new KungFuRole();
            // 开始演戏
            role.accept(actor);
        }
    }
    
    

    总结

    在上面的栗子中,角色只有在运行期间才能判断由那个演员执行,演员事先定义和那个角色绑定,所以角色使用接口,演员使用抽象类。

    接口,抽象类 接口呢 是在运行的时候才能发现,所以使用动态绑定,抽象类适合使用静态绑定。啊哈,这就是接口和抽象类的区别。

    访问者模式的核心在于定义一个方法,就像开启一个门,让访问者进入,然后在将其信息传递给访问者,由访问者执行需要产生的内容。

    应用

    过滤展示,报表,ui展示,过滤器,拦截器

    在无知的道路上缓步前行
  • 相关阅读:
    html抽取文本信息-java版(适合lucene建立索引)
    【LeetCode with Python】 Sort List
    POJ 2533 Longest Ordered Subsequence(dp LIS)
    Activity 之间 传递 List 封装的对象或者对象
    mongo数据库--非关系型数据库
    cocos2d-x的声音控制
    CSDN博客积分规则
    怎样使用递归实现归并排序
    android中9-patch图片的使用
    Cocos2d-x-3.0环境搭建
  • 原文地址:https://www.cnblogs.com/melovemingming/p/10312460.html
Copyright © 2020-2023  润新知