接上篇

一开始设计的BO 类是为了实现功能而实现功能

从类的单一职责的角度而言

先把这个BO对象拆分

 

这里又有一个需要考虑的点:   如何传递内表数据到ALV

如果引入一个中间变量,数据就会被double

alv大量数据显示也是常有的事,再double一下显然不可取

而且alv中修改了数据还得把修改的数据传回去  想想就麻烦

于是就想到了引用类型,这是个不错的解决方案

 

后来又反思了一下,

是否真的需要引用类型,是否有必要遵守严格的OO属性不对外公开

从写代码更简单,更快交付而言

在这个模型中把 要显示的内表声明为public 似乎更好一点

 

CLASS lcl_bo DEFINITION.
PUBLIC SECTION.
METHODS:
mock."模拟业务操作
DATA:
gt_bo TYPE tt_bo.
ENDCLASS. CLASS lcl_alv DEFINITION.
PUBLIC SECTION.
METHODS:
config," alv 显示参数
display CHANGING ct_table TYPE ANY TABLE."alv *
PRIVATE SECTION.
DATA:
gt_fieldcat TYPE lvc_t_fcat," 显示字段列表
gs_layout TYPE lvc_s_layo , " 页面布局
g_container TYPE REF TO cl_gui_custom_container, " 容器
g_grid TYPE REF TO cl_gui_alv_grid. " 显示Grid ENDCLASS. CLASS lcl_bo IMPLEMENTATION.
METHOD mock.
DATA: ls_bo TYPE ts_bo.
DO 10 TIMES.
ls_bo-datum = sy-datum + sy-index.
ls_bo-uzeit = sy-uzeit.
ls_bo-value = 'Times:' && sy-index.
APPEND ls_bo TO gt_bo.CLEAR ls_bo.
ENDDO.
ENDMETHOD. ENDCLASS. CLASS lcl_alv IMPLEMENTATION. METHOD config.
DATA:
ls_fieldcat TYPE lvc_s_fcat.
ls_fieldcat-fieldname = 'DATUM'.ls_fieldcat-coltext = '日期'. APPEND ls_fieldcat TO gt_fieldcat.CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'UZEIT'.ls_fieldcat-coltext = '时间'. APPEND ls_fieldcat TO gt_fieldcat.CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'VALUE'.ls_fieldcat-coltext = '内容'. APPEND ls_fieldcat TO gt_fieldcat.CLEAR ls_fieldcat. gs_layout-sel_mode = 'A'.
gs_layout-zebra = 'X' .
gs_layout-cwidth_opt = 'X'.
ENDMETHOD. METHOD display.
IF g_grid IS INITIAL.
CREATE OBJECT g_container
EXPORTING
container_name = 'C0100'. CREATE OBJECT g_grid
EXPORTING
i_parent = g_container. CALL METHOD g_grid->set_table_for_first_display
EXPORTING
* I_BUFFER_ACTIVE =
* I_CONSISTENCY_CHECK =
* I_STRUCTURE_NAME =
* is_variant = gs_variant
i_save = 'A'
i_default = 'X'
* is_layout = gs_layout
* IS_PRINT =
* IT_SPECIAL_GROUPS =
* it_toolbar_excluding = gt_exclude
* IT_HYPERLINK =
CHANGING
it_outtab = ct_table
it_fieldcatalog = gt_fieldcat
* it_sort = gt_sort
* IT_FILTER =
EXCEPTIONS
invalid_parameter_combination = 1
program_error = 2
too_many_lines = 3
OTHERS = 4.
ELSE.
CALL METHOD g_grid->refresh_table_display.
ENDIF. ENDMETHOD. "display ENDCLASS. DATA:
ok_code TYPE sy-ucomm,
go_bo TYPE REF TO lcl_bo,
go_alv TYPE REF TO lcl_alv. START-OF-SELECTION.
CREATE OBJECT go_bo.
CREATE OBJECT go_alv.
go_bo->mock( ).
go_alv->config( ).
CALL SCREEN 100. MODULE status_0100 OUTPUT.
SET PF-STATUS 'PS100'.
go_alv->display( CHANGING ct_table = go_bo->gt_bo ).
ENDMODULE. " STATUS_0100 OUTPUT MODULE user_command_0100 INPUT.
CASE ok_code.
WHEN 'BACK'.
SET SCREEN 0.
ENDCASE.
ENDMODULE. " USER_COMMAND_0100 INPUT

效果如下:

 

这个模型应该比上一个要好一点

BO中只关注业务逻辑,怎么显示全部交给ALV

 

如果严格的说遵循一些OO的编程规范

gt_bo是不可以放在public sction中的

那么传递数据使用需要稍微作一个变化

bo对象增加一个get_ref_table的方法

返回引用,对应的alv的display方法传入引用类型参数

代码就不写了

(在后续会讨论重用ALV对象

如果采用引用传递的话还有一个变化

定义一个通用接口 ,接口中就一个方法获取输出内表的引用

BO对象都要实现这个接口

ALV的display方法传入的参数就是这个接口对象)

 

* 这篇文章也是在上线期间事情不多的时候陆陆续续写的

* 又开始忙起来了,之后更新的速度可能就慢了(或者说又开始懒了)

* 大致把后续的思路也说一下吧

 

在当前模式下

一个BO  对应一个ALV

一般复杂一点的报表会有多个BO

也就有多个ALV

很自然会发现ALV的部分代码都是重复的

 

后续会讨论用抽象类实现ALV的基本功能

子类只关注fieldcat的编码

以及如何扩展抽象类的功能

使其适应项目中不同场景的要求

例如,隐藏工具栏,增加输出列,保持选中,启用变式等等

以及如何适应未来没有考虑到的扩展场景(其实就是预留一些方法,给子类重写而已)

当做到这一步的时候

其实会发现SAP已经帮我们都把这些事情做得差不多了

把我们的OO代码 同SAP的 REUSE_ALV_GRID_DISPLAY 结合

就是目前一直在做的事情

 

但是自定义的ALV有一个好处

可以把这个模型用到复杂的对话屏幕中

除了ALV还有其他控件 

所以自定义的ALV还是有用武之地的

如果单纯的做报表

那么推荐 OO + REUSE_ALV_GRID_DISPLAY

OO的代码处理核心业务逻辑

(还可以引入一些简单的设计模式,报表开发就会很happy~)

同时自定义的控件中封装REUSE_ALV_GRID_DISPLAY  显示也变得很简单

 

后续还会再写几个不同场景的示例出来

都是个人的一些思路,欢迎交流.

待续吧…

ABAP OO与ALV结合方式探索(2)的更多相关文章

  1. ABAP OO与ALV结合方式探索(1)

    用OO来开发,尤其是在复杂业务的开发过程中 从程序设计的角度而言,应该更简单一点 而ALV是二次开发中登场很高的一个控件 最近做了一些尝试,探索OO的代码和ALV的结合使用   使用控件型的ALV A ...

  2. ABAP OO的八大理由

    原贴地址:http://scnblogs.techweb.com.cn/abaplv/archives/127.html 几年前SAP BASIS 4.6为ABAP扩展了OO功能,这是很多传统的ABA ...

  3. OO的ALV隐藏工具栏的form

    OO的ALV隐藏工具栏: ***展示数据 CALL METHOD gr_alvgrid->set_table_for_first_display EXPORTING is_variant = g ...

  4. 通过接口标准化ABAP OO开发

    本文是对接口编程的讨论,希望能对年轻的开发者有所帮助. 要点: 通过接口对类方法进行更高层的抽象 接口使代码清晰易读 接口使你可以创建模拟对象(Mockup Object)以提高代码的可测试性 帮助实 ...

  5. ABAP分享二 ALV标准范例DEMO汇总

    SAP软件针对ALV的使用方法,提供了ALV标准demo程序: sap提供的ALV标准demo程序,只是展示简单的数据,用function ALV即可,若有复杂的增删改查操作 建议使用OO ALV,下 ...

  6. ABAP OO 开发语法整理

    [转自 http://blog.csdn.net/saphome/article/details/6956933] 在类中,只能用TYPE 附加关键字指定数据类型. •TYPES: 一般的类型定义方法 ...

  7. ABAP分享六 alv显示的几种方式的简单示例

    方法1,也是大家常见的方法通过函数   REUSE_ALV_GRID_DISPLAY TYPES: BEGIN OF  ty_spfli,   "定义结构     carrid like s ...

  8. ABAP分享五 ALV修改单元格并将修改数据更新到数据表中示例1

    *下面的代码是在alv字段中修改字段的内容,点击保存后就可以保存数据至数据表. TABLES: spfli. DATA: wa_fieldcat TYPE lvc_s_fcat ,  " 相 ...

  9. OO ALV 学习参考

      http://blog.csdn.net/sapliumeng/article/details/18653491 一.ALV介绍 The ALV Grid Control (ALV = SAPLi ...

随机推荐

  1. SMO优化算法(Sequential minimal optimization)

    原文:http://www.cnblogs.com/jerrylead/archive/2011/03/18/1988419.html SMO算法由Microsoft Research的John C. ...

  2. php 运行客户提交代码(攻击)和运行图片中的代码

    1.$a=@strrev(ecalper_gerp);$b=@strrev(edoced_46esab);@$a($b(L3h4L2Ug),$_POST[POST],bxxb); 2.<?php ...

  3. 【PHP代码审计】 那些年我们一起挖掘SQL注入 - 2.全局防护Bypass之UrlDecode

    0x01 背景 现在的WEB程序基本都有对SQL注入的全局过滤,像PHP开启了GPC或者在全局文件common.php上使用addslashes()函数对接收的参数进行过滤,尤其是单引号.遇到这种情况 ...

  4. 第一个c++程序 helloworld

    // helloworld.cpp : 定义控制台应用程序的入口点.// #include "stdafx.h"#include "iostream" int ...

  5. MySQL无视密码进入Server

    在[mysqld]的段中加上一句:skip-grant-tables 如下 [mysqld] skip-grant-tables 即可不输入密码就可以进入mysql server,然后就可以随便修改数 ...

  6. 集成支付宝钱包支付ios SDK的方法和经验

    没想到,支付宝的SDK是我目前用过的所有第三方SDK中最难用的一个了. 下载 首先,你要想找到这个SDK,都得费点功夫.现在的SDK改名叫移动支付集成开发包了,下载页面在 这里 的 “请点此下载集成开 ...

  7. postgres数据库中的数据转换

    postgres8.3以后,字段数据之间的默认转换取消了.如果需要进行数据变换的话,在postgres数据库中,我们可以用"::"来进行字段数据的类型转换.实际上"::& ...

  8. JavaSE——面向对象与面向过程、类与对象、(属性、方法、构造器)等

    一:面向对象与面向过程 二者都是一种思想,面向对象是相对于面向过程而言的. 面向过程: 1.面向过程思想强调的是过程(动作). 2.在面向过程的开发中,其实就是面向着具体的每一个步骤和过程,把每一个步 ...

  9. 数据结构【二】:简单阻塞队列BlockingQueue

    在POSIX多线程[一]:简单队列simple queue的基础上使用内部互斥锁和条件变量来控制并发以达到线程安全的目的,其主要用于 [生产者-消费者] 队列. 1.BlockingQueue初始化时 ...

  10. Ubuntu/Debian 安装lxml的正确方式

    lxml是Python的一个库,主要用于处理XML和HTML. 最近需要用lxml,但是在Ubuntu上直接pip安装失败,研究了半天终于找到了正确安装方法,记录在此. 由于Ubuntu和Debian ...