设计模式学习笔记:访问者模式(Visitor)

积极面对生活,善意的对待人和事物,回报将超乎你的想象。

一、访问者模式介绍

访问者模式是设计模式中行为型模式的一种。在访问者模式中,我们使用访问者类来改变元素类的执行算法。通过这种方式我们可以通过使用不同的访问者在不改变元素类的情况下改变其执行的算法。

其主要使用场景如下:

  1. 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。

  2. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。

二、实现

1、需求

公司里有不同岗位的员工,现需要访问这些员工的信息,员工的岗位类别基本固定,不同的访问者获取信息的逻辑不同。例如,获取基本信息的访问者只需获取员工姓名,获取详细信息的访问者除了获取姓名外还需要获取设计者正在设计的产品信息、销售员销售的产品的数量等。

2、设计

设计如下:访问者模式示例类图

3、代码实现

Visitor(访问者接口):

/**
 * 访问者接口
 *
 * @author ZhengNC
 * @date 2020/10/12 16:35
 */
public interface Visitor {

    /**
     * 访问销售人员
     *
     * @param salesman
     */
    void visit(Salesman salesman);

    /**
     * 访问设计者
     *
     * @param designer
     */
    void visit(Designer designer);
}

Staff(员工抽象类):

/**
 * 员工抽象类
 *
 * @author ZhengNC
 * @date 2020/10/12 16:32
 */
public abstract class Staff {

    private String name;

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

    /**
     * 获取员工姓名
     *
     * @return
     */
    public String getName(){
        return name;
    }

    /**
     * 访问员工(员工提供的接受访问的方法)
     *
     * @param visitor 访问者
     */
    public abstract void accept(Visitor visitor);
}

Salesman(销售人员(员工)):

import java.util.Random;

/**
 * 销售人员(员工)
 *
 * @author ZhengNC
 * @date 2020/10/12 16:45
 */
public class Salesman extends Staff {

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

    /**
     * 销售产品的数量
     */
    public int getNum(){
        return new Random().nextInt(100);
    }

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

Designer(设计师(员工)):

import java.util.UUID;

/**
 * 设计师(员工)
 *
 * @author ZhengNC
 * @date 2020/10/12 16:52
 */
public class Designer extends Staff {

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

    /**
     * 正在设计的产品
     */
    public String getProduct(){
        return UUID.randomUUID().toString()
                .replace("-", "")
                .substring(0, 5).toUpperCase();
    }

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

BaseVisitor(基本信息访问者):

/**
 * 基本信息访问者
 *
 * @author ZhengNC
 * @date 2020/10/13 9:54
 */
public class BaseVisitor implements Visitor{
    @Override
    public void visit(Salesman salesman) {
        System.out.println("销售员姓名:"+salesman.getName());
    }

    @Override
    public void visit(Designer designer) {
        System.out.println("设计师姓名:"+designer.getName());
    }
}

DetailVisitor(详细信息访问者):

/**
 * 详细信息访问者
 *
 * @author ZhengNC
 * @date 2020/10/13 9:59
 */
public class DetailVisitor implements Visitor {
    @Override
    public void visit(Salesman salesman) {
        System.out.println("销售员姓名:"+salesman.getName()+" \t"+
                "销售数量:"+salesman.getNum());
    }

    @Override
    public void visit(Designer designer) {
        System.out.println("设计师姓名:"+designer.getName()+" \t"+
                "正在设计的产品:"+designer.getProduct());
    }
}

DisplayInfoUtil(打印员工信息):

import java.util.ArrayList;
import java.util.List;

/**
 * 打印员工信息
 *
 * @author ZhengNC
 * @date 2020/10/13 10:05
 */
public class DisplayInfoUtil {

    private List<Staff> staffList;

    public DisplayInfoUtil(){
        staffList = new ArrayList<>();
        staffList.add(new Salesman("张三"));
        staffList.add(new Salesman("李四"));
        staffList.add(new Designer("王五"));
        staffList.add(new Designer("赵六"));
    }

    /**
     * 打印员工信息
     *
     * @param visitor
     */
    public void display(Visitor visitor){
        for (Staff staff : staffList){
            staff.accept(visitor);
        }
    }
}

4、测试访问者模式

TestVisitor(测试访问者模式):

/**
 * 测试访问者模式
 *
 * @author ZhengNC
 * @date 2020/10/13 10:10
 */
public class TestVisitor {

    public static void main(String[] args) {
        DisplayInfoUtil displayInfoUtil = new DisplayInfoUtil();

        //打印员工基本信息
        displayInfoUtil.display(new BaseVisitor());

        System.out.println("-------------------");

        //打印员工详细信息
        displayInfoUtil.display(new DetailVisitor());
    }
}

测试结果:

销售员姓名:张三
销售员姓名:李四
设计师姓名:王五
设计师姓名:赵六


销售员姓名:张三 销售数量:86
销售员姓名:李四 销售数量:23
设计师姓名:王五 正在设计的产品:8D7C8
设计师姓名:赵六 正在设计的产品:34BEA

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值