访问者模式

2018-05-05  本文已影响0人  joychic

定义

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

使用场景

结构

简单实现


public interface Visitor {

    void visit(Engineer engineer);

    void visit(Manager manager);
}

Visitor定义了一个visitor接口,有2个visit函数,对于Engineer、Manager的访问会调用2个不同的方法,以此达到差异化处理

public abstract class Staff {

    public String name;

    public int kpi;

    public Staff(String name) {
        this.name = name;
        kpi = new Random().nextInt(10);
    }

    public abstract void accept(Visitor visitor);
}

Staff为员工基类,定义了一个accept方法用来表示接受访问者访问,由子类具体实现

public class Manager extends Staff {
    private int products;

    public Manager(String name) {
        super(name);
        products = new Random().nextInt(10);
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public int getProducts() {
        return products;
    }
}

Manager为经理类

public class Engineer extends Staff {


    public Engineer(String name) {
        super(name);
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }


    /**
     * @return 工程师这一年的代码数量
     */
    public int getCodeLines() {
        return new Random().nextInt(10 * 10000);
    }

}

Engineer为工程师类

public class CTOVisitor 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());
    }
}

CTOVisitor为CTO访问者,关心技术贡献

public class CEOVisitor 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 + " ,新产品数量 :" + manager.getProducts());
    }
}

CEOVisitor为CEO访问者 只关注业绩

public class BusinessReport {

    List<Staff> mStaff = new LinkedList<>();

    public BusinessReport() {
        mStaff.add(new Manager("王经理"));
        mStaff.add(new Engineer("工程师-Shawn.Xiong"));
        mStaff.add(new Engineer("工程师-Kael"));
        mStaff.add(new Engineer("工程师-Jack"));
        mStaff.add(new Engineer("工程师-Rose"));
    }

    /**
     * 为访问者展示报表
     * @param visitor
     */
    public void showReport(Visitor visitor) {
        for (Staff staff : mStaff) {
            staff.accept(visitor);
        }
    }
}

BusinessReport为员工业务报表,访问者可以通过showReport函数查看所有员工的业绩

public class Client {
    public static void main(String[] args) {
        BusinessReport report = new BusinessReport();

        System.out.println("---------- 给 CEO 看的报表 -------------");

        report.showReport(new CEOVisitor());

        System.out.println("\n---------- 给 CTO 看的报表 -------------");

        report.showReport(new CTOVisitor());
    }
}

运行结果:

---------- 给 CEO 看的报表 -------------
经理 :王经理 , KPI0 ,新产品数量 :3
工程师 :工程师-Shawn.Xiong , KPI6
工程师 :工程师-Kael , KPI4
工程师 :工程师-Jack , KPI1
工程师 :工程师-Rose , KPI2

---------- 给 CTO 看的报表 -------------
经理 :王经理 ,新产品数量 :3
工程师 :工程师-Shawn.Xiong , 代码行数67720
工程师 :工程师-Kael , 代码行数37258
工程师 :工程师-Jack , 代码行数96044
工程师 :工程师-Rose , 代码行数3708
上一篇 下一篇

猜你喜欢

热点阅读