美文网首页Java 进阶
面向抽象编程、面向注解编程、现有框架的事实标准

面向抽象编程、面向注解编程、现有框架的事实标准

作者: 撸代码的大白 | 来源:发表于2020-04-22 10:56 被阅读0次

    一、面向抽象编程。

    为什么要面向抽象编程。说到底就是利用多态,实现运行时动态的确定具体实现。那为什么要运行时确定具体的实现呢?为了解耦和,通过接口或者抽象类,将具体实现的指定从编码阶段推迟到运行时,使原本的紧耦合变得松耦合。

    我们从场景出发:假如A使用B的功能,A持有B的引用。如果在编码阶段就具体制定B的引用指向的对象,那么就是紧耦合,因为A的对象和B的对象绑定了。但如果A只是持有B的引用,在编码阶段并不直接指定引用指向的对象,那么在运行之前,通过一系列操作,可以改变A引用B的对象具体是哪个。

    具体的好处在于,如果B的实现有几个,通过不同的场景决定实例化哪个,或者需要对B的对象进行代理增强等等,这个时候A的逻辑不需要做任何改动。如果A在编码阶段直接指定了B的实现,那么在一些需要替换或者增强的场景就无法动态的达成,必须要改A的代码。

    面向抽象编程就是在编码阶段使关系松散。具体操作的时候实际上是分两个步骤的。

    1、编码时不关心具体实现,只使用抽象(接口或者抽象类的方法)。也可以描述为,虽然我拿到得只是一个接口(抽象类),但是我假装我已经拿到了某个实现。因为给我的返回结果的结构是一样的。

    2、依赖注入或者依赖查找。代表的是IOC/DI和SPI。因为编码时不关心实例化的问题,但是实例化的工作总得做。依赖注入或者依赖查找就是将编码阶段没有赋值的引用实例化赋值。

    第一步是我们编写业务代码时做的。

    第二步是框架替我们做的。

    二、面向注解编程。

    面向注解编程可以理解为一种思想,但在面向抽象编程的理解过程,我们可以发现面向注解的很多场景都是为了动态增强。当然这只是注解的一部分功能。

    在面向抽象的基础上,只要是符合抽象规则的实现类都可以被赋值到引用内。意味着框架层面可以对原有的类在符合抽象规则的基础上(实现接口或者继承),添加一些原有逻辑之外的功能。比如如说事务、日志、自定义的业务逻辑等等。

    这种做法旨在提供一个开发的思路,比如功能开发只开发功能本身,对功能的修饰、增强等的不是核心逻辑的代码可以通过注解的方式增加上去。

    这样功能逻辑会变得简洁,代码复用提高。而且当修饰或者增强的功能发生迭代时,原有的功能逻辑代码不受影响。


    三、现有框架的事实标准。

    事实上目前我们开发已经遵循了上述的两个原则。现在主流的springboot、springmvc。都是分层且面向接口的。职责明确之余,当某一层的功能改变时,一般不会波及到其他层,或尽量少的波及到其他层。

    除了上述的原则之外,因为各层多是无状态的,如果有一些状态一般会存储在一些线程私有的结构中去,所以尽可能的保证了线程安全。这也是为什么很多程序员不懂或者不关注线程安全的原因。因为无状态不存在线程安全问题。

    那对于开发人员要做的就是,理解框架做的事儿,不要人为的打破,不然当遇到扩展、增强、替换等场景时,很多本来可行的方案会面临巨大的改造量。

    举一个例子。A模块使用了B模块的功能,现在要做微服务拆分。方案为,对B的service层的接口提供一个新的实现。由本地调用改为远程调用。通过配置文件控制是原来的模式还是微服务模式。假设原有的为ServiceBimpl1,改造后的实现为ServiceBimpl2。因为是面向接口编程的,所以只需要控制具体实例化哪个实现,A模块内的代码不需要做改动,改动点被屏蔽在ServiceBimpl2内部。然而现实情况为,A并没有单纯的通过B的service层进行引用,对B功能的各层都有引用,这就导致很大的工作量。

    这只是替换的场景。很多场景下,我们都希望一些公用的功能对业务代码无侵入,无侵入的设计时,会默认业务场景遵循了规则,理解规则,不打破规则是开发人员需要具备的素质。

    相关文章

      网友评论

        本文标题:面向抽象编程、面向注解编程、现有框架的事实标准

        本文链接:https://www.haomeiwen.com/subject/mksbihtx.html