博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
访问者模式
阅读量:7073 次
发布时间:2019-06-28

本文共 8062 字,大约阅读时间需要 26 分钟。

首先

抽象员工

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 + "\t";        info = info + "性别" + this.sex + "\t";        info = info + "薪水" + this.salary + "\t";        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 + "\t";    }}

管理层

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 + "\t";    }}

最后场景

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() + "\t";        info = info + "性别" + (employee.getSex() == Employee.FEMALE?"女","男");        info = info + "薪水" + employee.getSalary() + "\t";        return info;    }    // 组装普通员工信息    private String getCommonEmployee(CommonEmployee commonEmployee){        String basicinfo = this.getBasicinfo(commonEmployee);        String otherinfo = "工作" + commonEmployee.getJob() + "\t";        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展示,过滤器,拦截器

图片描述

转载地址:http://wqkml.baihongyu.com/

你可能感兴趣的文章
忘记Mysql的root密码怎么办?
查看>>
ODBC CRecordSet访问
查看>>
Codeforces Gym 100015C City Driving 离线LCA
查看>>
JavaScript基础:数据类型的中的那些少见多怪
查看>>
C#入门经典Lambda
查看>>
佛山Uber优步司机奖励政策(1月25日~1月31日)
查看>>
随机IP代理
查看>>
怎么提高ArcGIS for Desktop10.x的性能
查看>>
python文件相关操作
查看>>
socket.io+angular.js+express.js做个聊天应用(四)
查看>>
PLSQL Developer过期要注冊表
查看>>
JavaScript中call,apply,bind方法的总结。
查看>>
Ajax、Comet与Websocket
查看>>
Python输出中文乱码问题
查看>>
HDU 5655 CA Loves Stick 水题
查看>>
EventBus (四) Sticky事件
查看>>
linux Shell编程
查看>>
HTML元素坐标定位,这些知识点得掌握
查看>>
【服务器环境搭建-Centos】jdk的安装
查看>>
mysql主从复制的配置总结
查看>>