访问者模式实战

44 阅读1分钟

1. 模式说明

抽象出访问接口和抽象类,通过这种不确定性能梳理出业务的结构,虽然代码结构复杂了,但是业务代码解耦了

2. demo

业务知识如下图,vistor访问老师和学生关注的信息不一样

image.png


/**
 * 用户类
 */
public abstract class User {

    // 姓名
    public String name;
    // 身份;重点班、普通班 | 特级教师、普通教师、实习教师
    public String identity;
    // 班级
    public String clazz;

    public User(String name, String identity, String clazz) {
        this.name = name;
        this.identity = identity;
        this.clazz = clazz;
    }

    // 核心访问方法
    public abstract void accept(Visitor visitor);

}
// 学生
public class Student extends User {

    public Student(String name, String identity, String clazz) {
        super(name, identity, clazz);
    }

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

    public int ranking() {
        return (int) (Math.random() * 100);
    }

    public int count() {
        return 105 - new Random().nextInt(10);
    }

}
public class Teacher extends User {

    public Teacher(String name, String identity, String clazz) {
        super(name, identity, clazz);
    }

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

    // 升本率
    public double entranceRatio() {
        return BigDecimal.valueOf(Math.random() * 100).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

}
/**
 * 访问者接口
 */
public interface Visitor {

    // 访问学生信息
    void visit(Student student);

    // 访问老师信息
    void visit(Teacher teacher);

}

/**
 * 家长
 */
public class Parent implements Visitor {

    private Logger logger = LoggerFactory.getLogger(Parent.class);

    @Override
    public void visit(Student student) {
        logger.info("学生信息 姓名:{} 班级:{} 排名:{}", student.name, student.clazz, student.ranking());
    }

    @Override
    public void visit(Teacher teacher) {
        logger.info("老师信息 姓名:{} 班级:{} 级别:{}", teacher.name, teacher.clazz, teacher.identity);
    }

}

/**
 * 校长
 */
public class Principal implements Visitor {

    private Logger logger = LoggerFactory.getLogger(Principal.class);

    @Override
    public void visit(Student student) {
        logger.info("学生信息 班级:{} 人数:{}", student.clazz, student.count());
    }

    @Override
    public void visit(Teacher teacher) {
        logger.info("学生信息 姓名:{} 班级:{} 升学率:{}", teacher.name, teacher.clazz, teacher.entranceRatio());
    }

}

接口测试


public class ApiTest {

    private Logger logger = LoggerFactory.getLogger(ApiTest.class);

    @Test
    public void test_show(){
        DataView dataView = new DataView();

        logger.info("家长视角访问:");
        dataView.show(new Parent());

        logger.info("校长视角访问:");
        dataView.show(new Principal());
    }

}

3. 应用