访问者模式

Android进阶之设计模式

访问者模式

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

使用场景:

  1. 对象结构比较稳定,但经常需要再此对象结构上定义新的操作.
  2. 需要对一个对象结构中的对象进行很多不同的而且不相关的操作,而需要避免这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类.

优点:

  1. 各角色职责分离,符合单一职责原则;
  2. 具有优秀的扩展性;
  3. 使得数据结构和作用于结构上操作解耦,使得操作集合可以独立变化;
  4. 灵活性;

缺点:

  1. 具体元素对访问者公布细节,违反了迪米特原则;
  2. 具体元素变更时导致修改成本大;
  3. 违反了依赖倒置原则,为了达到"区别对待"而依赖了具体类,没有依赖抽象;

举个例子:


//员工基类
public abstract class Staff {
    public String name;

    //员工kpi
    public int kpi;

    public Staff(String name) {
        this.name = name;
    }

    //接受Visitor的访问
    public abstract void accept(Visitor visitor);
}


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.visitor(this);
    }

    //一年内做的产品数量
    public int getProducts(){
        return products;
    }
}


public class Engineer extends Staff{
    public Engineer(String name) {
        super(name);
    }

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

    //码农一年写了代码行数
    public int getCodeLine(){
        return new Random().nextInt(10*1000);
    }
}

public interface Visitor {

    public void visitor(Engineer engineer);

    public void visitor(Manager manager);
}

public class CEOVisitor implements Visitor{
    @Override
    public void visitor(Engineer engineer) {
        System.out.println("码农:"+engineer.name+ " ,  KPI : "+engineer.kpi);
    }

    @Override
    public void visitor(Manager manager) {
        System.out.println("经理 : "+ manager.name +" , KPI : "+manager.kpi+" , 新产品数量 : "+ manager.getProducts());
    }
}


public class CTOVisitor implements Visitor{
    @Override
    public void visitor(Engineer engineer) {
        System.out.println("码农 : " + engineer.name +" , 代码行数  :"+ engineer.getCodeLine());
    }

    @Override
    public void visitor(Manager manager) {

        System.out.println("经理 : "+manager.name +" , 产品数量 : "+ manager.getProducts());
    }
}


//员工报表1
public class BusinessReport {

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

    public BusinessReport() {

        staff.add(new Manager("王经理"));
        staff.add(new Engineer("码农-小张"));
        staff.add(new Engineer("码农-小李"));
        staff.add(new Engineer("码农-小陈"));
        staff.add(new Engineer("码农-小钱"));
    }


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

 public static void main(String[] args) {
 
 
        BusinessReport report = new BusinessReport();
        System.out.println("===============CEO===========");
        report.showReport(new CEOVisitor());
        System.out.println("===============CTO===========");
        report.showReport(new CTOVisitor());

}

推荐阅读更多精彩内容

  • 【学习难度:★★☆☆☆,使用频率:★★★☆☆】直接出处:访问者模式梳理和学习:https://github.com...
    BruceOuyang阅读 573评论 2 2
  • 1 场景问题# 1.1 扩展客户管理的功能## 考虑这样一个应用:扩展客户管理的功能。 既然是扩展功能,那么肯定是...
    七寸知架构阅读 1,829评论 1 55
  • 目录 本文的结构如下: 引言 什么是访问者模式 模式的结构 典型代码 访问者模式中的伪动态双分派 代码示例 访问者...
    w1992wishes阅读 436评论 0 6
  • 介绍 访问者模式的基本思想是,软件系统中拥有一个由许多对象构成的,比较稳定的对象结构,这些对象的类都拥有一个 ac...
    任教主来也阅读 126评论 0 1
  • 纳兰玲珑/文 小时候 妈妈总是说 在村东头的池塘边 有一颗粗壮的柳树 环抱的树干 温顺地放下长发 垂进了岸边 柳树...
    纳兰玲珑阅读 116评论 2 16