一种用于ABAP Report重构的面向对象设计方法——MVC
2017-10-26 10:53
309 查看
原文地址:http://zevolving.com/2013/03/abap-object-oriented-approach-for-reports-redesign/
By Naimesh Patel | March 27, 2013 | ABAP Objects, OO Design Patterns
在本篇文章中,我将使用ABAP对象向你展示一种更加灵活的设计。该设计用于尽可能的解耦业务逻辑、参数、数据展示。
介绍
如前一篇文章讨论所述(一种用于ABAP面向对象的Report的初始设计,其得到了非常好的反响),我看到很多开发者在试图使用面向对象时遵循了糟糕的设计。由于那样的设计没有利用任何面向对象的特性,我通常将他们成为伪对象设计。
我将向你展示如何用面向对象的设计实现我在前一篇文章中提到的例子。这个方法纯粹基于MVC的设计模式。如果你对MVC还不是很熟悉,我建议你可以阅读我更早的3篇系列文章——可以从《ABAP Objects Design Patterns – Model View Controller (MVC) Part 1》这篇开始。
相关对象
为制作这个简单的报表程序,我将创建三个类:
SEL-选择参数类
DATA(Model)-数据选择和处理类(类似于模型类)
ALV(View)-用于展示数据的类
这里所有的想法都是为了尽可能的解耦。所以,基于此,我将把所有与业务逻辑相关的数据选择和处理都放在DATA类中。这个DATA类将有不同的方法去检索和处理基于选择参数的数据。为了避免把选择条件作为参数嵌入在DATA类中,我将它们放在一个单独的类中-SEL类。这将给我一个优势,可以将SEL对象传递给DATA类和ALV类(如果需要那样做的话)。下一步是解耦报表程序的显示相关功能。所以我会创建一个ALV类。
UML设计
uml基本设计如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201710/23248667d97020b9f339aad19f255ec1)
另外我已经创建了一个Exception类ZCX_MSG,用于处理来自于对象模型的例外情况。如果你还不熟悉基于Exception的类,我建议你读一下我的另一个系列文章,可以从《Class-based Exceptions I – Basics》开始学习如何使用它。
SEL类
SEL类负责在需要的时候将属性传递给模型和视图。因为选择参数没有被嵌入在模型类中,你可以简单的将对象传递给另一个模型类。SEL类的职责和属性:
包含所有来自于选择屏幕的参数和选项
包含选择屏幕上的自动生成的默认值的方法
包含验证选择屏幕数据合法性的方法
所有属性将仅在处理START-OF-SELECTION事件时被设置
Demo:SEL类的代码行——ZCL_REPORT_T100_SEL
这个SEL类的例子包含两个属性用于保存选择条件。它还有两个方法,GET_DEFAULT方法用于设置默认值,VALIDATE_MESSAGE_CLASS用于参数合法性验证。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201710/3f72e8734876db3d9c424fdfdfddd60d)
ZCL_REPORT_T100_SEL代码行:
DATA类
DATA类负责抓取数据并以期望的格式输出。典型的数据类职责如下:
包含用于数据选择的所有方法
将使用来自于SEL对象的属性用于数据选择和筛选
将包含实例属性。仅仅只有一个需要被暴露给外界的属性被声明为Public,剩下的全部声明为Private。
这可以反过来根据需要使用不同的对象
Demo:DATA类——ZCL_REPORT_T100_DATA
这个类包含两个属性:O_SEL——类型为ZCL_REPORT_T100_SEL,T_T100——类型为TABLE T100,用于存放筛选后的数据。在构造方法中,我们为O_SEL做初始化赋值。GET_DATA方法使用SEL对象的属性筛选数据。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201710/5a8027ae071ca4e58fbdd11dad60cf9b)
DATA类ZCL_REPORT_T100_DATA的代码行:
ALV类
典型的View类负责向调用者显示数据以及任何处理操作。ALV类:
将包含有关ALV处理的逻辑
也包含用于处理任何需要事件的事件处理方法
将包含一个DATA类的属性。这是一个Public属性,因此外部将可以获取DATA的内容。
Demo:ALV类——ZCL_REPORT_T100_ALV
这个类包含两个属性:ZCL_REPORT_T100_DATA类型的O_DATA和CL_SALV_TABLE类型的O_SALV。包含一些方法:构造方法用于设置DATA对象,GENERATE_ALV用于声场简单的ALV报表。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201710/a67a84a0a91d5394313b059188d42654)
ALV类ZCL_REPORT_T100_ALV的代码行:
基于面向对象设计方法的程序
这是根据以上声明的类重新设计的程序代码版本。
demo程序的UML
这是从UML角度看以上程序的样子。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201710/124a8532f6957f32cee5987f8a1fca18)
优点
这种面向对象的设计确实比面向过程的方法需要更多的努力来实现,但是这将获得更多的灵活性以及更少的维护——降低总体拥有成本(TCO)。
由于模型类从主程序中解耦出来,它独立运作。这样使得它能更加方便的扩展并可用于不同的视图中。
分离的SEL对象使得不用在方法中与使用选择屏幕参数和选项耦合。这比使用任何选择屏幕更加独立。只要你设置合适的属性,你将能够用DATA类来使用它。
分离视图提高了可重用性
考虑一下用同样的逻辑开发一个WebDynpro——设置合适的参数给SEL对象,实例化DATA类并调用方法获得数据。将数据传递给视图WebDynpro去生成输出。
或者,想一想,有一个已存在的复杂设计需要展示这些数据,可以以上述同样的方法直接获取你所期望的数据输出。
你怎么认为?
你会愿意使用这样的设计吗?你认为它是一个好方法吗?或者是一个过度设计?
By Naimesh Patel | March 27, 2013 | ABAP Objects, OO Design Patterns
在本篇文章中,我将使用ABAP对象向你展示一种更加灵活的设计。该设计用于尽可能的解耦业务逻辑、参数、数据展示。
介绍
如前一篇文章讨论所述(一种用于ABAP面向对象的Report的初始设计,其得到了非常好的反响),我看到很多开发者在试图使用面向对象时遵循了糟糕的设计。由于那样的设计没有利用任何面向对象的特性,我通常将他们成为伪对象设计。
我将向你展示如何用面向对象的设计实现我在前一篇文章中提到的例子。这个方法纯粹基于MVC的设计模式。如果你对MVC还不是很熟悉,我建议你可以阅读我更早的3篇系列文章——可以从《ABAP Objects Design Patterns – Model View Controller (MVC) Part 1》这篇开始。
相关对象
为制作这个简单的报表程序,我将创建三个类:
SEL-选择参数类
DATA(Model)-数据选择和处理类(类似于模型类)
ALV(View)-用于展示数据的类
这里所有的想法都是为了尽可能的解耦。所以,基于此,我将把所有与业务逻辑相关的数据选择和处理都放在DATA类中。这个DATA类将有不同的方法去检索和处理基于选择参数的数据。为了避免把选择条件作为参数嵌入在DATA类中,我将它们放在一个单独的类中-SEL类。这将给我一个优势,可以将SEL对象传递给DATA类和ALV类(如果需要那样做的话)。下一步是解耦报表程序的显示相关功能。所以我会创建一个ALV类。
UML设计
uml基本设计如下:
另外我已经创建了一个Exception类ZCX_MSG,用于处理来自于对象模型的例外情况。如果你还不熟悉基于Exception的类,我建议你读一下我的另一个系列文章,可以从《Class-based Exceptions I – Basics》开始学习如何使用它。
SEL类
SEL类负责在需要的时候将属性传递给模型和视图。因为选择参数没有被嵌入在模型类中,你可以简单的将对象传递给另一个模型类。SEL类的职责和属性:
包含所有来自于选择屏幕的参数和选项
包含选择屏幕上的自动生成的默认值的方法
包含验证选择屏幕数据合法性的方法
所有属性将仅在处理START-OF-SELECTION事件时被设置
Demo:SEL类的代码行——ZCL_REPORT_T100_SEL
这个SEL类的例子包含两个属性用于保存选择条件。它还有两个方法,GET_DEFAULT方法用于设置默认值,VALIDATE_MESSAGE_CLASS用于参数合法性验证。
ZCL_REPORT_T100_SEL代码行:
* Types for the Attributes TYPES: tt_MSGNR_Range TYPE RANGE OF t100-MSGNR . DATA V_ARBGB TYPE T100-ARBGB . DATA T_MSGNR_RANGE TYPE TT_MSGNR_RANGE . * CLASS ZCL_REPORT_T100_SEL IMPLEMENTATION. METHOD GET_DEFAULT. " returning value(RV_ARBGB) type T100-ARBGB . rv_arbgb = '00'. ENDMETHOD. * METHOD validate_message_class. " importing !IV_ARBGB type T100-ARBGB " raising ZCX_MSG . DATA: ls_msg TYPE symsg. SELECT SINGLE arbgb INTO v_arbgb FROM t100 WHERE arbgb = iv_arbgb. IF sy-subrc NE 0. ls_msg-msgty ='E'. ls_msg-msgid ='00'. ls_msg-msgno = '398'. ls_msg-msgv1 = 'No Message class found'. RAISE EXCEPTION TYPE zcx_msg EXPORTING msg = ls_msg. ENDIF. ENDMETHOD. ENDCLASS.
DATA类
DATA类负责抓取数据并以期望的格式输出。典型的数据类职责如下:
包含用于数据选择的所有方法
将使用来自于SEL对象的属性用于数据选择和筛选
将包含实例属性。仅仅只有一个需要被暴露给外界的属性被声明为Public,剩下的全部声明为Private。
这可以反过来根据需要使用不同的对象
Demo:DATA类——ZCL_REPORT_T100_DATA
这个类包含两个属性:O_SEL——类型为ZCL_REPORT_T100_SEL,T_T100——类型为TABLE T100,用于存放筛选后的数据。在构造方法中,我们为O_SEL做初始化赋值。GET_DATA方法使用SEL对象的属性筛选数据。
DATA类ZCL_REPORT_T100_DATA的代码行:
CLASS ZCL_REPORT_T100_DATA IMPLEMENTATION. METHOD CONSTRUCTOR. " importing !IO_SEL type ref to ZCL_REPORT_T100_SEL . me->o_Sel = io_sel. ENDMETHOD. * METHOD GET_DATA. SELECT * FROM t100 INTO TABLE t_t100 WHERE arbgb = me->o_sel->v_arbgb AND msgnr IN me->o_Sel->T_MSGNR_RANGE. ENDMETHOD. ENDCLASS.
ALV类
典型的View类负责向调用者显示数据以及任何处理操作。ALV类:
将包含有关ALV处理的逻辑
也包含用于处理任何需要事件的事件处理方法
将包含一个DATA类的属性。这是一个Public属性,因此外部将可以获取DATA的内容。
Demo:ALV类——ZCL_REPORT_T100_ALV
这个类包含两个属性:ZCL_REPORT_T100_DATA类型的O_DATA和CL_SALV_TABLE类型的O_SALV。包含一些方法:构造方法用于设置DATA对象,GENERATE_ALV用于声场简单的ALV报表。
ALV类ZCL_REPORT_T100_ALV的代码行:
CLASS ZCL_REPORT_T100_ALV IMPLEMENTATION. METHOD CONSTRUCTOR. " importing !IO_DATA type ref to ZCL_REPORT_T100_DATA . me->o_Data = io_data. ENDMETHOD. * METHOD GENERATE_ALV. TRY. CALL METHOD cl_salv_table=>factory IMPORTING r_salv_table = me->o_salv CHANGING t_table = me->o_data->t_t100. * me->o_salv->display( ). * CATCH cx_salv_msg . ENDTRY. ENDMETHOD. ENDCLASS.
基于面向对象设计方法的程序
这是根据以上声明的类重新设计的程序代码版本。
*&---------------------------------------------------------------------* *& Purpose - Object Oriented Implementation for a Repor 4000 t *& Author - Naimesh Patel *& URL - http://zevolving.com/?p=2045 *&---------------------------------------------------------------------* REPORT ztest_np_t100_OO_report. * DATA: v_msgnr TYPE t100-msgnr. " for selection screen * DATA: o_data TYPE REF TO zcl_report_t100_data. DATA: o_sel TYPE REF TO zcl_report_t100_sel. DATA: o_alv TYPE REF TO zcl_report_t100_alv. DATA: o_exc TYPE REF TO zcx_msg. * SELECTION-SCREEN: BEGIN OF BLOCK blk1 WITH FRAME TITLE text-t01. PARAMETERS: p_arbgb TYPE t100-arbgb OBLIGATORY. SELECT-OPTIONS: s_msgno FOR v_msgnr. SELECTION-SCREEN: END OF BLOCK blk1. * INITIALIZATION. CREATE OBJECT o_sel. CREATE OBJECT o_data EXPORTING io_sel = o_sel. CREATE OBJECT o_alv EXPORTING io_data = o_data. p_arbgb = o_sel->get_default( ). * AT SELECTION-SCREEN ON p_arbgb. TRY. o_sel->validate_message_class( p_arbgb ). CATCH zcx_msg INTO o_exc. MESSAGE ID o_exc->msg-msgid TYPE o_exc->msg-msgty NUMBER o_exc->msg-msgno WITH o_exc->msg-msgv1 o_exc->msg-msgv2 o_exc->msg-msgv3 o_exc->msg-msgv4. ENDTRY. * START-OF-SELECTION. " Set the attributes of the SEL object from the " Selection screen parameters & Options o_sel->v_arbgb = p_arbgb. o_sel->t_msgnr_range = s_msgno[]. * * Get the data o_data->get_data( ). * * Generate the ALV o_alv->generate_alv( ).
demo程序的UML
这是从UML角度看以上程序的样子。
优点
这种面向对象的设计确实比面向过程的方法需要更多的努力来实现,但是这将获得更多的灵活性以及更少的维护——降低总体拥有成本(TCO)。
由于模型类从主程序中解耦出来,它独立运作。这样使得它能更加方便的扩展并可用于不同的视图中。
分离的SEL对象使得不用在方法中与使用选择屏幕参数和选项耦合。这比使用任何选择屏幕更加独立。只要你设置合适的属性,你将能够用DATA类来使用它。
分离视图提高了可重用性
考虑一下用同样的逻辑开发一个WebDynpro——设置合适的参数给SEL对象,实例化DATA类并调用方法获得数据。将数据传递给视图WebDynpro去生成输出。
或者,想一想,有一个已存在的复杂设计需要展示这些数据,可以以上述同样的方法直接获取你所期望的数据输出。
你怎么认为?
你会愿意使用这样的设计吗?你认为它是一个好方法吗?或者是一个过度设计?
相关文章推荐
- Java面向对象基础--类的设计及分析问题的方法---用户登录例子
- MVC是一种用于表示层设计的复合设计模式
- ASP.NET MVC 学习笔记-3.面向对象设计原则
- 再探结构化设计和面向对象设计方法
- C#面向对象设计模式纵横谈(四) --- Factory Method 工厂方法(创建型模式)
- 测试面向对象软件时,设计集成测试用例的方法
- 面向对象与结构化软件设计方法的实践对比(有点意思)
- MVC是一种用于表示层设计的复合设计模式
- 面向对象建模与数据库建模两种分析设计方法的比较
- 重构-改善既有代码的设计:对象之间移动特性的八种方法(五)
- 黑马程序员——面向对象思想、设计类与创建对象、对象与函数、方法与函数、合理设计类
- 重构-改善既有代码的设计:对象之间移动特性的八种方法(五)
- 再探结构化设计和面向对象设计方法
- 面向对象建模与数据库建模两种分析设计方法的比较
- 面向对象设计:共性VS个性-------继承的粒度和聚合的粒度以及类的重构
- 重构-改善既有代码的设计:对象之间移动特性的八种方法(五)
- 面向对象设计原则和创建SOLID应用的5个方法
- c#面向对象系列4(设计方法模式)
- 面向对象设计方法理解
- java基础——面向对象设计方法