0.3、Spring源码学习-从一个UML模型讲起

版权声明:欢迎转载交流,声明出处即可。体能状态先于精神状态,习惯先于决心,聚焦先于喜好 ——Bestcxx https://blog.csdn.net/bestcxx/article/details/90706166

前言

体能状态先于精神状态,习惯先于决心,聚焦先于喜好。

本文的灵感

最近的几个星期笔者在工作开发和Sping 源码学习中看到了一些“新奇”的代码写法,与此产生了一些灵感。

开发中遇到的情况是这样的,笔者需要对一个对账功能进行改造,现有程序有两个特点,一个是对账功能无法指定时间,由定时任务调用,总是生成昨天的定时任务;第二个特点是由于对接了多家公司,而每个公司对账形式又不相同。改造的点在于需要提供一个接口,允许按照指定日期生成对账文件,但是不能影响原有的功能。
正常来说,我需要新增一个以时间作为入参的方法即可。但是这样做的话每个公司的对账逻辑我都需要进行变动——系统现存的定时任务调用的方法并没有入参。
惊奇的是我发现代码结构使用了 接口-父类-子类 的形式,其中父类中提供了 private 修饰的时间参数和 get、set 方法,与此同时接口中有给时间赋值的抽象方法
这样一来我的改造思路就变为了-先调用给时间赋值的方法,然后调用原先的对账文件的方法,跟踪代码逻辑可以发现,需要将系统中获取时间的地方全部由“获取昨天”修改为“如果时间参数不为空则获取昨天,否则就获取指定的时间参数”-在工具类中增加这个方法即可,然后重构测试后就搞定了

在查看Spring 源码的过程中,发现了这样的情况,Spring 的顶层是接口,有些接口甚至是没有抽象方法的,然后这些接口被子类实现,子类又有新的子类,这样也可以简化出一个 接口-父类-子类的结构,而接口可以使用父类或者子类实例化,而子类可以复用父类中的方法。这对于Spring 从不同的来源加载配置文件提供了极大的方便

给出一个UML图

依据上面讨论的 接口-父类-子类 模型,笔者做了进一步的延伸,就是提供两个接口,并且这两个接口中拥有一个一模一样的抽象方法。

在这里插入图片描述

提出第一个问题

InterfaceA 和 InterfaceB 中拥有相同的抽象方法 sayHello(),类 FirstClass 需要重写几个 sayHello()方法?

答案是一个。 这意味着,如果我们只是想调用 sayHello()方法,使用InterfaceA 或者 InterfaceB 来进行Spring 注入效果是一样的。

提出第二个问题

InterfaceA 可否被 Sub1Class 实例化(或者进行Spring注入),FirstClass是否可以被Sub1Class 实例化(或者进行Spring注入)?

答案是:可以;可以。从子类实现接口和子类继承父类来说,这都是Java 继承机制的体现,但是有一点是需要注意的,Spring 默认使用的是 JDK 动态代理,需要借助于接口进行注入,虽然Spring 也支持cglib 动态代理,但是在进行FirstClass 注入Sub1Class时有可能会报无法找到代理类的问题。

接口-父类-子类 模型的好处

这种模型的好处在于,当我们新增一个功能的时候可以通过一个新的接口去声明,然后在父类中实现,而子类可以直接调用,但是不需要做额外的工作,对于功能扩展来说对代码的改动是非常友好的。

猜你喜欢

转载自blog.csdn.net/bestcxx/article/details/90706166