zoukankan      html  css  js  c++  java
  • 在ABAP里模拟实现Java Spring的依赖注入

    Dependency Injection- 依赖注入,在Java Spring框架中有着广泛地应用。通过依赖注入,我们不必在应用代码里繁琐地初始化依赖的资源,非常方便。

    那么ABAP能否从语言层面上也支持依赖注入,享受这种设计思路带来的便利呢?让我们做一次尝试。

    尝试的场景

    在现实生活中,每一盏灯都有一个开关控制。按下开关,灯被打开;再按一次,灯熄灭。

    先看不使用依赖注入的常规实现:

    设计一个ABAP interface ZIF_SWITCHABLE,提供两个方法,分别对应开和关。

    自然的,我有一个ABAP 类 ZCL_LAMP,用于实现上述接口。每个ZCL_LAMP的实例就是一盏灯。

    CLASS ZCL_LAMP IMPLEMENTATION.
    
    method ZIF_SWITCHABLE~OFF.
    
    WRITE: / 'lamp off'.
    
    endmethod.
    
    method ZIF_SWITCHABLE~ON.
    
    WRITE: / 'lamp on'.
    
    endmethod.
    
    ENDCLASS.
    

    再设计一个开关类,这个类有一个成员变量mo_switchable, 指向ZIF_SWITCHABLE这个接口。

    开关有个“按”的方法。按下之后,如果当前状态是开,那么就调用mo_switchable成员的off方法,将其关闭,并设置开关状态为关闭。反之亦然。

    METHOD push.
    
    IF isswitchon = abap_true.
    
    mo_switchable->off( ).
    
    isswitchon = abap_false.
    
    ELSE.
    
    mo_switchable->on( ).
    
    isswitchon = abap_true.
    
    ENDIF.
    
    ENDMETHOD.
    

    提供一个setter方法,将传入的类型为ZIF_SWITCHABLE的变量注入到成员变量mo_switchable中。

    method SET_SWITCHABLE.
    
    mo_switchable = io_switchable.
    
    endmethod.
    

    我把迄今为止创建的两个类:ZCL_LAMP和ZCL_SWITCH都放到package $ZDEV_INVERSION内。

    ABAP Summer框架的消费代码

    从下图的代码能看出,ZCL_SWITCH和ZCL_LAMP产生了强依赖关系。这种依赖关系是应用开发人员调用set方法手动注入的。

    总结一下,上图代码有哪些是在Java Spring里完全能够通过依赖注入的思想来避免的。

    line 8: 手工创建ZCL_LAMP(灯)的实例。

    line 9: 手工创建ZCL_SWITCH(开关)的实例。

    line 11: 调用set方法手动注入灯和开关的依赖关系。

    使用ABAP Summer框架实现依赖注入

    我自己用ABAP模拟了Java Spring的依赖注入框架,开发了一个原型,取名ABAP Summer,与Java的Spring相呼应。

    先想想这个简单的例子用Java Spring如何实现。一个Java程序员很容易就能写出下面的代码,利用Spring的注解@Inject,我们无需手动实例化ISwitchable和调用set方法建立依赖。一切由Spring框架帮我们实现了。

    现在,怎样用ABAP实现这些“魔术”?

    1. 在ZCL_SWITCH类的成员变量mo_switchable的描述字段里加上注解@Inject,意图是告诉ABAP Summer框架,我希望mo_switchable成员能够自动被注入一个正确的依赖进来。到底什么样的依赖算正确?Summer框架如何知道该怎样注入?请继续阅读。

    注意:ABAP这门语言同Java不同,无法在语言层面支持注解,因此这里在Description字段上维护的@Inject只是一个模拟。

    2. 先看采用了依赖注入之后的ABAP消费代码,是不是一下子清爽了很多?

    data(summer) = zcl_summer=>get_instance( ).
    
    data(lo_switch) = cast zcl_switch( summer->get_bean( EXPORTING iv_bean_name = 'ZCL_SWITCH' ) ).
    
    lo_switch->push( ).
    
    lo_switch->push( ).
    

    下图是基于ABAP常规实现和基于ABAP依赖注入思想的两套消费代码的比较,能清晰发现,采取了ABAP依赖注入后,

    之前提到的这三处手动操作完全得到避免。GET_BEAN方法返回的开关实例,里面的成员变量mo_switchable包含的就是自动注入好的ZCL_LAMP类的实例。

    line 8: 手工创建ZCL_LAMP(灯)的实例。

    line 9: 手工创建ZCL_SWITCH(开关)的实例。

    line 11: 调用set方法手动注入灯和开关的依赖关系。

    让我们再看看Java Spring里正宗的消费代码,确保我们发明的ABAP Summer确实是原汁原味的依赖注入。

    ABAP Summer依赖注入的实现原理

    这个ABAP依赖注入框架的实现在我的github上:

    https://github.com/i042416/jerryslide/tree/master/ABAP/summer

    关于Java Spring依赖注入的讲解,网上有很多写得很精彩的著作。

    下面是ABAP Summer依赖注入的核心实现,参考了上图著作关于Java Spring的讲解。

    要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:

  • 相关阅读:
    本博客停止更新说明
    JavaScript备忘录(3)——正则表达式
    JavaScript备忘录(2)——闭包
    JavaScript备忘录(1)——内置类型
    CSS布局:Float布局过程与老生常谈的三栏布局
    地图投影简明笔记
    Three.js源码阅读笔记-5
    js中 set, map区别
    Package.json详解
    node.js 中的package.json文件怎么创建?
  • 原文地址:https://www.cnblogs.com/sap-jerry/p/9817598.html
Copyright © 2011-2022 走看看