作者:小傅哥
博客: https://bugstack.cn - 原创系列专题文章
沉淀、分享、成长,让自己和他人都能有所收获!:smile:
能力,是你前行的最大保障
年龄会不断的增长,但是什么才能让你不慌张。一定是能力,即使是在一个看似还很安稳的工作中也是一样,只有拥有 能留下的本事
和 跳出去的能力
,你才会是安稳的。而能力的提升是不断突破自己的未知也就是拓展宽度,以及在专业领域建设个人影响力也就是深度。如果日复日365天,天天搬砖,一切都没有变化的重复只能让手上增长点老茧,岁月又叹人生苦短。
站得高看的远吗?
站得高确实能看得远,也能给自己更多的追求。但,站的高了,原本看的清的东西就变得看不清了。视角和重点的不同,会让我们有很多不同的选择,而脚踏实地是给自己奠定能攀升起来的基石,当真的可以四平八稳的走向山头的时候,才是适合看到更远的时候。
数学好才能学编码吗
往往很多时候学编程的初学者都会问数学不好能学会吗?其实可以想想那为什么数学不好呢?在这条没学好的路上,你为它们付出了多少时间呢?如果一件事情你敢做到和写自己名字一样熟悉,还真的有难的东西吗。从大学到毕业能写出40万行代码的,还能愁找不到工作吗,日积月累,每一天并没有多难。难的你想用最后一个月的时间学完人家四年努力的成绩的。学习,要趁早。
bugstack虫洞栈
,回复 源码下载
获取(打开获取的链接,找到序号18) 工程 | 描述 |
---|---|
itstack-demo-design-22-00 | 场景模拟工程;模拟学生和老师信息不同视角访问 |
访问者要解决的核心事项是,在一个稳定的数据结构下,例如用户信息、雇员信息等,增加易变的业务访问逻辑。为了增强扩展性,将这两部分的业务解耦的一种设计模式。
说白了访问者模式的核心在于同一个事物不同视角下的访问信息不同,比如一个 美女
手里拿个 冰激凌
。小朋友会注意冰激凌,大朋友会找自己喜欢的地方观测敌情。
这个案例场景我们模拟校园中有学生和老师两种身份的用户,那么对于家长和校长关心的角度来看,他们的视角是不同的。家长更关心孩子的成绩和老师的能力,校长更关心老师所在班级学生的人数和升学率{ 此处模拟的
}。
那么这样 学生
和 老师
就是一个固定信息的内容,而想让不同视角的用户获取关心的信息,就比较适合使用观察者模式来实现,从而让实体与业务解耦,增强扩展性。 但观察者模式的整体类结构相对复杂,需要梳理清楚再开发
访问者模式的类结构相对其他设计模式来说比较复杂,但这样的设计模式在我看来更加 烧气有魅力
,它能阔开你对代码结构的新认知,用这样思维不断的建设出更好的代码架构。
关于这个案例的核心逻辑实现,有以下几点;
itstack-demo-design-22-00 └── src ├── main │ └── java │ └── org.itstack.demo.design │ ├── user │ │ ├── impl │ │ │ ├── Student.java │ │ │ └── Teacher.java │ │ └── User.java │ ├── visitor │ │ ├── impl │ │ │ ├── Parent.java │ │ │ └── Principal.java │ │ └── Visitor.java │ └── DataView.java └── test └── java └── org.itstack.demo.design.test └── ApiTest.java
以上是视图展示了代码的核心结构,主要包括不同视角下的不同用户访问模型。
在这里有一个关键的点非常重要,也就是整套设计模式的核心组成部分; visitor.visit(this)
,这个方法在每一个用户实现类里,包括; Student
、 Teacher
。在以下的实现中可以重点关注。
// 基础用户信息 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); }
abstract void accept(Visitor visitor)
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 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); } }
accept
方法中,提供了本地对象的访问; visitor.visit(this)
,这块需要加深理解。 entranceRatio
)、排名( ranking
),类似这样的方法可以按照业务需求进行扩展。 public interface Visitor { // 访问学生信息 void visit(Student student); // 访问老师信息 void visit(Teacher teacher); }
public class Principal implements Visitor { private Logger logger = LoggerFactory.getLogger(Principal.class); public void visit(Student student) { logger.info("学生信息 姓名:{} 班级:{}", student.name, student.clazz); } public void visit(Teacher teacher) { logger.info("学生信息 姓名:{} 班级:{} 升学率:{}", teacher.name, teacher.clazz, teacher.entranceRatio()); } }
public class Parent implements Visitor { private Logger logger = LoggerFactory.getLogger(Parent.class); public void visit(Student student) { logger.info("学生信息 姓名:{} 班级:{} 排名:{}", student.name, student.clazz, student.ranking()); } public void visit(Teacher teacher) { logger.info("老师信息 姓名:{} 班级:{} 级别:{}", teacher.name, teacher.clazz, teacher.identity); } }
public class DataView { List<User> userList = new ArrayList<User>(); 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); } } }
观察者(校长、家长)
@Test public void test(){ DataView dataView = new DataView(); logger.info("/r/n家长视角访问:"); dataView.show(new Parent()); // 家长 logger.info("/r/n校长视角访问:"); dataView.show(new Principal()); // 校长 }
23:00:39.726 [main] INFO org.itstack.demo.design.test.ApiTest - 家长视角访问: 23:00:39.730 [main] INFO o.i.demo.design.visitor.impl.Parent - 学生信息 姓名:谢飞机 班级:一年一班 排名:62 23:00:39.730 [main] INFO o.i.demo.design.visitor.impl.Parent - 学生信息 姓名:windy 班级:一年一班 排名:51 23:00:39.730 [main] INFO o.i.demo.design.visitor.impl.Parent - 学生信息 姓名:大毛 班级:二年三班 排名:16 23:00:39.730 [main] INFO o.i.demo.design.visitor.impl.Parent - 学生信息 姓名:Shing 班级:三年四班 排名:98 23:00:39.730 [main] INFO o.i.demo.design.visitor.impl.Parent - 老师信息 姓名:BK 班级:一年一班 级别:特级教师 23:00:39.730 [main] INFO o.i.demo.design.visitor.impl.Parent - 老师信息 姓名:娜娜Goddess 班级:一年一班 级别:特级教师 23:00:39.730 [main] INFO o.i.demo.design.visitor.impl.Parent - 老师信息 姓名:dangdang 班级:二年三班 级别:普通教师 23:00:39.730 [main] INFO o.i.demo.design.visitor.impl.Parent - 老师信息 姓名:泽东 班级:三年四班 级别:实习教师 23:00:39.730 [main] INFO org.itstack.demo.design.test.ApiTest - 校长视角访问: 23:00:39.731 [main] INFO o.i.d.design.visitor.impl.Principal - 学生信息 姓名:谢飞机 班级:一年一班 23:00:39.731 [main] INFO o.i.d.design.visitor.impl.Principal - 学生信息 姓名:windy 班级:一年一班 23:00:39.731 [main] INFO o.i.d.design.visitor.impl.Principal - 学生信息 姓名:大毛 班级:二年三班 23:00:39.731 [main] INFO o.i.d.design.visitor.impl.Principal - 学生信息 姓名:Shing 班级:三年四班 23:00:39.733 [main] INFO o.i.d.design.visitor.impl.Principal - 学生信息 姓名:BK 班级:一年一班 升学率:70.62 23:00:39.733 [main] INFO o.i.d.design.visitor.impl.Principal - 学生信息 姓名:娜娜Goddess 班级:一年一班 升学率:23.15 23:00:39.734 [main] INFO o.i.d.design.visitor.impl.Principal - 学生信息 姓名:dangdang 班级:二年三班 升学率:70.98 23:00:39.734 [main] INFO o.i.d.design.visitor.impl.Principal - 学生信息 姓名:泽东 班级:三年四班 升学率:90.14 Process finished with exit code 0
排名:62
、 排名:51
、 排名:16
、 排名:98
。 升学率:70.62
、 升学率:23.15
、 升学率:70.98
、 升学率:90.14
。 if