项目踩坑Android进阶Android开发经验谈

访问者模式

2019-03-22  本文已影响5人  程序员丶星霖

《Android源码设计模式解析与实战》读书笔记(十六)
《Android源码设计模式解析与实战》PDF资料下载

一、访问者模式简介

访问者模式是一种将数据操作与数据结构分离的设计模式。

访问者模式的基本想法是,软件系统中拥有一个由许多对象构成的、比较稳定的对象结构,这些对象的类都拥有一个accept方法用来接受访问者对象的访问。

1.1、定义

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

1.2、使用场景

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

二、访问者模式的简单示例

public abstract class Staff {
    public String name;
    //员工kpi
    public int kpi;

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

    //接受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);
    }
    //工程师这一年写的代码数量
    public int getCodeLines() {
        return new Random().nextInt(10 * 10000);
    }
}
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;
    }
}
public interface Visitor {
    //访问工程师类型
    public void visit(Engineer engineer);
    //访问经理类型
    public void visit(Manager manager);
}
//员工业务报表1类
public class BusinessReport {
    List<Staff> mStaffs = new LinkedList<>();

    public BusinessReport() {
        mStaffs.add(new Manager("王经理"));
        mStaffs.add(new Engineer("工程师—Shawn.Xiong"));
        mStaffs.add(new Engineer("工程师——Kael"));
        mStaffs.add(new Engineer("工程师-Chaosssss"));
        mStaffs.add(new Engineer("工程师-Tiiime"));
    }

    /**
     * 为访问者展示报表
     */
    public void showReport(Visitor visitor) {
        for (Staff staff : mStaffs) {
            staff.accept(visitor);
        }
    }
}
//CEO访问者,只关注业绩
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());
    }
}
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 report = new BusinessReport();
        System.out.println("============给CEO看的报表===========");
        //设置访问者,这里是CEO
        report.showReport(new CEOVisitor());
        System.out.println("\n==================给CTO看的报表=========================");
        //注入另一个访问者,CTO
        report.showReport(new CTOVisitor());
    }
}

输出结果:

访问者模式.png

三、总结

3.1、优点

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

3.2、缺点

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

学海无涯苦作舟

我的微信公众号
上一篇 下一篇

猜你喜欢

热点阅读