设计模式

访问者模式(Visitor)

2020-07-21  本文已影响0人  秀儿2020

定义

表示一个作用于某对象结构中的各元素的操作,他使你可以在不改变各元素的类的前提下定义作用与这些元素的新操作。

本质

预留通路,回调实现

登场角色

示例代码

/**
 * Element 元素抽象类
 */
public abstract class Staff {
    public String name;
    public int kpi;
    public Staff(String name) {
        this.name = name;
        kpi = new Random().nextInt(10);
    }
    /**
     * 接受Visitor的访问
     * @param 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);
    }
    /**
     * 工程师这一年的代码量
     * @return
     */
    public int getCodeLines(){
        return new Random().nextInt(10000);
    }
}

/**
 * 具体的元素,经理
 */
public class Manager extends Staff{
    public Manager(String name) {
        super(name);
    }

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

    /**
     * 一年内做的产品的数量
     * @return
     */
    public int getProducts(){
        return new Random().nextInt(100);
    }
}

public class BusinessReport {
    public List<Staff> mStaffs = new ArrayList<>();

    public BusinessReport() {
        mStaffs.add(new Manager("王经理"));
        mStaffs.add(new Engineer("工程师1"));
        mStaffs.add(new Engineer("工程师2"));
    }

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

/**
 * CEO Visitor
 * 只关注工程师的KPI、经理的KPI以及新产品数量
 */
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());
    }
}


/**
 * CTO访问者
 * 只关注工程师的代码行数和经理的产品数量
 */
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());
    }
}


/**
 * 测试
 */
public class Client {
    public static void main(String[] args){
        BusinessReport businessReport = new BusinessReport();
        System.out.println("======给CEO看的报表=======");
        businessReport.showReports(new CEOVisitor());
        System.out.println("======给CTO看的报表=======");
        businessReport.showReports(new CTOVisitor());
    }
}

运行结果

======给CEO看的报表=======
经理 : 王经理, KPI : 9,新产品数量:6
工程师 : 工程师1, KPI : 0
工程师 : 工程师2, KPI : 9
======给CTO看的报表=======
经理 : 王经理, 产品数量 : 43
工程师 : 工程师1, 代码行数 : 9902
工程师 : 工程师2, 代码行数 : 5611

功能

访问者模式能给一系列对象透明的添加新功能,从而避免在维护期间对这一系列对象进行修改,而且还能变相实现复用访问者所具有的功能。

优点

缺点

使用场景

上一篇 下一篇

猜你喜欢

热点阅读