文章目录
访问者模式
- 访问者模式
- 访问者模式实战
在相同的数据结构下, 增加容易变化的业务访问逻辑, 为了增强扩展性, 将易变的访问逻辑进行解耦的一种设计模式.
访问者模式实战模拟学校中, 有老师和学生, 也有家长和校长这两种数据访问的模式. 该设计模式的类图如下 抽象用户类
User
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 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.name, student.clazz);
}
@Override
public void visit(Teacher teacher) {
// 校长看老师的升学率
logger.info("老师信息 姓名:{} 班级:{} 升学率:{}", teacher.name, teacher.clazz, teacher.entranceRatio());
}
}
数据看板类
public class DataView {
List userList = new ArrayList();
public DataView() {
userList.add(new Student("谢飞机", "重点班", "一年一班"));
userList.add(new Student("windy", "重点班", "一年一班"));
userList.add(new Student("大毛", "普通班", "二年三班"));
userList.add(new Student("Shing", "普通班", "三年四班"));
userList.add(new Teacher("BK", "特级教师", "一年一班"));
userList.add(new Teacher("娜娜Goddess", "特级教师", "一年一班"));
userList.add(new Teacher("dangdang", "普通教师", "二年三班"));
userList.add(new Teacher("泽东", "实习教师", "三年四班"));
}
// 展示
public void show(Visitor visitor) {
for (User user : userList) {
user.accept(visitor);
}
}
}
测试类
public class ApiTest {
private Logger logger = LoggerFactory.getLogger(ApiTest.class);
@Test
public void test() {
DataView dataView = new DataView();
logger.info(" 家长视角: ");
dataView.show(new Parent());
logger.info("校长视角: ");
dataView.show(new Principal());
}
}
测试结果如下
15:55:30.023 [main] INFO com.thc.test.ApiTest - 家长视角:
15:55:30.031 [main] INFO com.thc.design.visitor.impl.Parent - 学生信息 姓名: 谢飞机 班级:一年一班, 排名:16
15:55:30.031 [main] INFO com.thc.design.visitor.impl.Parent - 学生信息 姓名: windy 班级:一年一班, 排名:4
15:55:30.031 [main] INFO com.thc.design.visitor.impl.Parent - 学生信息 姓名: 大毛 班级:二年三班, 排名:36
15:55:30.031 [main] INFO com.thc.design.visitor.impl.Parent - 学生信息 姓名: Shing 班级:三年四班, 排名:30
15:55:30.031 [main] INFO com.thc.design.visitor.impl.Parent - 老师信息 姓名:BK 班级:一年一班 级别:特级教师
15:55:30.031 [main] INFO com.thc.design.visitor.impl.Parent - 老师信息 姓名:娜娜Goddess 班级:一年一班 级别:特级教师
15:55:30.031 [main] INFO com.thc.design.visitor.impl.Parent - 老师信息 姓名:dangdang 班级:二年三班 级别:普通教师
15:55:30.031 [main] INFO com.thc.design.visitor.impl.Parent - 老师信息 姓名:泽东 班级:三年四班 级别:实习教师
15:55:30.031 [main] INFO com.thc.test.ApiTest - 校长视角:
15:55:30.032 [main] INFO c.thc.design.visitor.impl.Principal - 学生信息 姓名:谢飞机 班级:一年一班
15:55:30.033 [main] INFO c.thc.design.visitor.impl.Principal - 学生信息 姓名:windy 班级:一年一班
15:55:30.033 [main] INFO c.thc.design.visitor.impl.Principal - 学生信息 姓名:大毛 班级:二年三班
15:55:30.033 [main] INFO c.thc.design.visitor.impl.Principal - 学生信息 姓名:Shing 班级:三年四班
15:55:30.036 [main] INFO c.thc.design.visitor.impl.Principal - 老师信息 姓名:BK 班级:一年一班 升学率:81.75
15:55:30.036 [main] INFO c.thc.design.visitor.impl.Principal - 老师信息 姓名:娜娜Goddess 班级:一年一班 升学率:71.87
15:55:30.036 [main] INFO c.thc.design.visitor.impl.Principal - 老师信息 姓名:dangdang 班级:二年三班 升学率:41.04
15:55:30.036 [main] INFO c.thc.design.visitor.impl.Principal - 老师信息 姓名:泽东 班级:三年四班 升学率:58.41
可以看到家长和校长虽然都打印的是学生和教师, 但家长可以看到学生的排名, 校长可以看到教师的升学率.