1. 模式说明
抽象出访问接口和抽象类,通过这种不确定性能梳理出业务的结构,虽然代码结构复杂了,但是业务代码解耦了
2. demo
业务知识如下图,vistor访问老师和学生关注的信息不一样
/**
* 用户类
*/
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());
}
}