我目前正在开发一个相当复杂的ABAP应用程序,该应用程序将被分成几个模块,每个模块执行工作的特定部分:
- 一个用于从多个来源收集一些数据;
- 一个用于在 UI 中显示该数据(SALV 网格,如果这很重要(;
- 一个用于根据该数据做一些业务。
根据我的计划,每个模块都将是一个全局类。但是,可能需要在这些类之间共享一些逻辑:帮助程序子例程、数据库访问逻辑等。目前所有这些都是一组本地类。
我知道这些类也可以是全球性的,但这意味着将它们(以及一些内部数据结构(公开给公众,我不想这样做。另一种方法是在我的全局类之间与他们共享包含,但据说这是一个糟糕的设计。
所以,我的问题是:真正的ABAPer如何解决这样的问题?
下面是如何访问报表中定义的本地类的示例。
与类一起报告。
REPORT ZZZ_PJ1.
CLASS lcl_test DEFINITION FINAL.
PUBLIC SECTION.
METHODS:
test.
ENDCLASS.
CLASS lcl_test IMPLEMENTATION.
METHOD test.
WRITE 'test'.
ENDMETHOD.
ENDCLASS.
使用该类的报告。
REPORT ZZZ_PJ2.
CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS:
main.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
METHOD main.
DATA:
lr_object TYPE REF TO object.
CREATE OBJECT lr_object
TYPE ('PROGRAM=ZZZ_PJ1CLASS=LCL_TEST')
CALL METHOD lr_object->('TEST').
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
lcl_main=>main( ).
当然,这不是一个聪明的解决方案,因为每个方法调用都必须是动态调用。
CALL METHOD lr_object->('TEST').
但是,这可以通过使用全局接口来解决,该接口将定义类的方法(当然,如果它们不是静态的,我认为它们不是(。然后,您必须通过界面控制每个实例。然后,您的目标将实现,因为只有接口将全局公开,实现将保留在本地类中。
您可能想阅读一些有关模型-视图-控制器设计模式的内容。在 UI 中显示数据 - 将是一个"视图"。 数据的收集和更新都将纳入一个"模型"。业务逻辑应该在"控制器"中实现为视图和模型之间的交互。
也就是说,一种方法是利用ABAP OO中提供的友谊功能。
例如:创建模型并全局查看类,但只允许私下实例化它们,然后授予私有组件对控制器的访问权限。类定义如下:
CLASS zcl_example_view DEFINITION
PUBLIC
FINAL
CREATE PRIVATE
GLOBAL FRIENDS zcl_example_controller
CLASS zcl_example_model DEFINITION
PUBLIC
FINAL
CREATE PRIVATE
GLOBAL FRIENDS zcl_example_controller
CLASS zcl_example_controller DEFINITION
PUBLIC
FINAL
CREATE PUBLIC
此外,最好使控制器成为单一实例,并在视图和模型中存储对它的引用。通过强制控制器在实例化视图和模型时IS BOUND
,我们可以有效地确保这三个类仅按您希望的方式存在。
回到你最初的问题:在我看来,你已经在开发中使用了MVC模式之类的东西,所以你唯一的问题是一些例程应该被模型、视图和控制器公开使用。
在这种情况下,我强烈建议将这些例程放在全局可用类中,或者在现有类中实现 getter 方法以访问这些功能。
任何像PROGRAM=ZZZ_PJ1CLASS=LCL_TEST
这样的黑客有时是必不可少的,但恕我直言,这里不是。
如果您的应用程序与您听起来的大小一样大,则应使用多个包来组织它。您肯定必须处理非OO的东西,例如函数模块,数据字典对象和其他不能成为类一部分的东西,因此使用类作为组织应用程序的基本方法在非常小和专门的应用程序之外是行不通的。
此外,如果您认为"数据库访问逻辑"应该"在类之间共享",那么听起来您的计划中嵌入了一些非常严重的缺陷。如果没有进一步的信息,很难猜测,但我强烈建议您招募具有设计和实现这种规模应用程序经验的人 - 至少要正确理解基本概念。