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的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:

在ABAP里模拟实现Java Spring的依赖注入的更多相关文章

  1. Java Spring各种依赖注入注解的区别

    Spring对于Bean的依赖注入,支持多种注解方式: @Resource javax.annotation JSR250 (Common Annotations for Java) @Inject ...

  2. 详解Java Spring各种依赖注入注解的区别

    注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired.Resource.Qualifier.Service.Controller.Repository.Comp ...

  3. spring的依赖注入是什么意思

    最近学习spring框架,对依赖注入有些模糊,遂上网翻阅资料,做了下列总结,原博客为CSDN 南夏的 spring的依赖注入是什么意思,侵删! Spring 能有效地组织J2EE应用各层的对象.不管是 ...

  4. Spring.NET依赖注入框架学习--入门

    Spring.NET依赖注入框架学习--入门 在学些Spring.net框架之前,有必要先脑补一点知识,比如什么是依赖注入?IOC又是什么?控制反转又是什么意思?它们与Spring.net又有什么关系 ...

  5. spring中依赖注入

    理解依赖注入:参考https://blog.csdn.net/taijianyu/article/details/2338311 一.依赖注入让bean与bean之间以配置文件组织在一起,而不是以硬编 ...

  6. Spring系列.依赖注入配置

    依赖注入的配置 Spring的依赖注入分为基于构造函数的依赖注入和基于setter方法的依赖注入. 基于构造函数的依赖注入 <!-- 通过构造器参数索引方式依赖注入 --> <bea ...

  7. (spring-第3回【IoC基础篇】)spring的依赖注入-属性、构造函数、工厂方法等的注入(基于XML)

    Spring要把xml配置中bean的属性实例化为具体的bean,"依赖注入"是关卡.所谓的"依赖注入",就是把应用程序对bean的属性依赖都注入到spring ...

  8. Spring的依赖注入(DI)三种方式

    Spring依赖注入(DI)的三种方式,分别为: 1.  接口注入 2.  Setter方法注入 3.  构造方法注入 下面介绍一下这三种依赖注入在Spring中是怎么样实现的. 首先我们需要以下几个 ...

  9. 一步一步深入spring(3)--spring的依赖注入方式

    对于spring配置一个bean时,如果需要给该bean提供一些初始化参数,则需要通过依赖注入方式,所谓的依赖注入就是通过spring将bean所需要的一些参数传递到bean实例对象的过程,sprin ...

随机推荐

  1. HDOJ-1004(map)

    Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  2. 7、html的body内标签之图片及表格

    一.image <a href="https://www.baidu.com" target="_blank"> <img src=" ...

  3. ElasticSearch入门及核心概念介绍

      Elasticsearch研究有一段时间了,现特将Elasticsearch相关核心知识和原理以初学者的角度记录下来,如有不当,烦请指正! 0. 带着问题上路——ES是如何产生的? (1)思考:大 ...

  4. 多叉树结构:JSON数据解析(一)

    多叉树结构:JSON数据解析(一) 最近做一个实时数据搜索引擎的项目中,在项目架构的偏顶层需要写一个JSON数据解析的模块,由于目前JSON解析没有现成统一开源框架可以利用,目前只是手工利用com.a ...

  5. 洛谷 - P1891 - 疯狂LCM - 线性筛

    另一道数据范围不一样的题:https://www.cnblogs.com/Yinku/p/10987912.html $F(n)=\sum\limits_{i=1}^{n} lcm(i,n) $ $\ ...

  6. html扩展调用qq聊天窗口

    需要在官方给qq开通客服功能,使用相应的html代码,别人才能通过链接调用到该qq 官方生成调用链接 over!over!over!

  7. apache2.4.35 403 forbidden 解决办法

  8. __str__,__repr__

    目录 __str__ __repr__ __str__ 打印时触发 class Foo: pass obj = Foo() print(obj) <__main__.Foo object at ...

  9. 在指定的ChartArea中显示Series

    WinForm的Chart有Series, ChartArea,输出图表就往Serie里扔数据就可以了,很方便是吧.我原想Area和serie有上下级关系,可是我错了,Area和Serie并没有上下级 ...

  10. bzoj2825:[AHOI2012]收集资源

    传送门 看到数据范围这么小,就没想过暴力的办法么 考虑肯定是从近走到远,所以走的点之间一定没有其他的点,所以我们就可以暴力的建图,然后暴力的去dfs就好了 代码: #include<cstdio ...