BADI的工作原理(转自吕中奇的belong)

 

Class是object的抽象描述,object只是在程序运行时才能存在。Object是由class描述的,并包含两个层次,inner layer和outer layer。Object的public component就是这个object的interface。Oo的主要目的就是为了保证object本身状态的consistency。Object的attributes一般是internal的,只能被它的method修改。对于具有相同attributes和methods的object他们也有自己的identity来区分。与OO概念相似的有function group,不同的是function group只能有一个instance,而object可以有任意个instance。

       Interface是独立于class之外定义的。.它包含向attributes和methods这样的声明语句。其具体功能是通过class来实现的。这些class应该有统一的与外部联系的方式,并通过实现方法来实现interface的所有功能。在程序中你可以创建interface变量来指向interface,但是你不能instantiate一个interface。Interface变量用来指向不同class的object。

       与customer exit不同的是,badi考虑到了软件修改的发布流程。Badi enhancement的实现至少需要一个interface以及相应的class来实现它,interface的实现由用户来完成。这种enhancement的一个优点是它提供了reuse的能力。一旦实现了,badi在软件的发布过程中仍然可以重新实现。Implementation本身也可以提供badi。

       一个badi包含着enhancement components,其主要包含下面几种components:

l         Program enhancements:program enhancements是通过interface methods来实现的,SAP程序来调取生成的badi class的interface methods。

l         Menu enhancements:同customer exit一样,可以在badi中维护function code。这些menu entry在GUI definition中已经定义就可以在implemented badi看见。

l         Screen enhancements:同customer exit一样你可以在badi中维护screen enhancements。

创建badi时,几个相关的部件就会被创建:interface和为实现interface而生成的class。生成的class主要实现下面的任务:过滤,如果你实施了一个过滤badi,那么这个class就会保证只有相关的implementation才会被调用。

Badi的执行流程:首先service class CL_EXITHANDLER会创建一个object reference,并产生调用program enhancement method的条件。当你定义BADI时,就会产生一个BADI class,用来implement badi interface。调用时,badi class的interface method就会被调用。Badi会搜索所有的BADI Implementation并调用implemented methods。

Badi在调用程序中的实现源代码如下:

REPORT <program_using_badi>.

DATA: r_var TYPE REF TO <badi-interface>.

START-OF-SELECTION.

CALL METHOD cl_exithandler=>get_instance

       CHANGING

              Instance = r_var.

CALL METHOD r_var->method

       EXPORTING

              <i_variables>

       IMPORTING

              <e_variables>.

END-OF-SELECTION.

首先你必须定义一个指向badi interface的reference variable。这个reference variable的名字不一定要包括badi的名字。第一次调用时一个object reference就会被创建,只用interface的method才会被这个reference object调用。可以通过这个reference object来调用你需要的enhancement中的方法。

可以通过t-code SE19来implement badi。

可以给implement class分配任何的名字,不过最好遵循以下规则:namespace以Y或Z开始,对于class的name以CL开始,implementation的name以IM开始,要implement method只要双击method name即可,系统会自动启动Class Builder editor。一旦完成代码编写,一定要激活它。

如果badi被激活,当调用程序执行时,相应的implementation methods也会被执行。一旦diactivate这个implementation,相应的方法就不会被调用。然而应用程序中的相关调用仍然会被执行。不同的是adapter class的instance不会找到激活的implementations。并不像CALL CUSTOMER-FUNCTION,CALL METHOD CL_EXITHANDLER=>GET_INSTANCE即使没用implementations,仍然会被调用。只有在original system中才可以activate或deactivate implementations,而subsequent systems则只能transport。如果badi只能有一个implementation,那么系统中仍然可以存在这个badi的多个implementation,只不过只能有一个激活版本。

同customer exit一样badi中也有menu enhancements。但是必须满足以下两个条件:1,必须预留了menu enhancement。2,必须在Badi的implementation中实现。Menu enhancements的function codes必须以+开始。如果相应的enhancement的badi implementation被激活,那么menu就会显示出来。你只能为single use badi创建function code,而且badi不能是filter dependent。这样就保证了一个或多个的badi不出现矛盾。如果用户在程序中选择了相应的以+开始的function code,那么系统就会调用相应的method。Method call和Menu enhancement是不可分离的,它们只能属于同一个badi。

       通过badi builder SE18来创建badi。Badi有两个重要的属性,Reusable和filter-dependent。如果想让你的badi支持多个激活的implementation那么就要选择reusable。不过implementations的执行顺序不能被定义。即使badi本身不支持mulitiple use也可以同时存在多个implementations,只不过只能有一个激活的implementation。Badi如果filter dependent的,这样就可以设置调用的条件。Filter type必须是data element或者ABAP dictionary structure。Data element使用的domain的value table包含了implementation所需要的valid values。如果filter type使用的是structure,那么这适用于structure的每个字段。当调用enhancement method时,filter value必须传给interface。Badi中可以包含function code,需要输入program name,function code以及short description。局限性是不能够创建只包含function code的badi,menu enhancement既不能filter dependent也不能reusable。

       系统提供了badi的interface和生成class的name。理论上可以将这些name改成任何你喜欢的name,但是保留系统推荐的name会使badi更加容易理解。生成的class的name遵循以下规则:namespace prefix + CL_ + EX_(代表 exit) + badi name。双击interface name就会进入class builder,就可以定义interface method。一个badi indterface可以有多个interface method。Class bulder的所有功能都可以使用,如定义interface method,定义method的interface parameters以及声明interface的attributes等。如果badi是filter dependent的,必须给他的每个method定义一个import parameter flt_val。一旦完成了interface的定义就要激活它。一旦修改了interface,badi class也会重新生成。也可以在badi维护事务中通过utilities->Regenerate来重新生成adapter class。Badi在程序中的调用过程:首先声明一个badi interface的reference variable。调用service class CL_EXITHANDLER的static method GET_INSTANCE。这个method返回required object的instance。这里属于narrow cast,所以通过这个variable只能调用interface methods。然后你就可以调用badi的方法了。示例如下:

DATA: r_var TYPE REF TO <badi-interface>.

START-OF-SELECTION.

CALL METHOD

       Cl_exithandler=>get_instance

              CHANGING

                     Instance = r_var.

CALL METHOD r_var-><method>

       EXPORTING

              <i_variables>

       IMPORTING

              <e_variables>/

如果使用filter dependent badi,要给参数flt_val传递一个适当的值。

对于ABAP virtual machine,screens和class是不能绑定到一块的。所以只用classical programs(type I,For M)才能作为screen的容器。Badi的screen enhancement也必须考虑到这点。当创建badi screen enhancement时,在应用程序的screen上要保留一块subscreen area。然后implementing program就会填充它。应用程序和subscreen的container program并不直接交换信息,而是通过生成的badi class。如果badi包含screen enhancements那么它就不能是reusable的。在subscreen tab你需要输入calling program,screen number和subscreen area。Implementing program和subscreen number是在implementation过程中指定的。

如果想通过badi实现screen enhancement,在应用程序中要实现以下步骤:

l         生成badi class

l         将badi class instance存入到refernce variable中

l         将数据传递给badi class

l         得到enhancement screen的program name和screen number

l         调用screen

在main screen的PAI,需要调用另外一个method把修改后的数据传回给application program。

实现screen enhancement的几个步骤:

l         首先通过adapter class CL_EXITHANDLER的factory method get_instance来得到生成的badi class的一个instance。并将其存储到一个reference variable中。DATA:EXIT TYPE REF TO <badi-interface>. CALL METHOD cl_exithandler=>get_instance CHANGING instance = exit.

l         然后implementation必须能够access badi instance。也就是说必须把reference variable赋给handler class的一个attribute。然后这个reference variable就会赋给badi class。通过下面的语句来实现这个步骤:CALL MEHTOD cl_exithandler=>set_instance_for_subsdcreens

l         为了使implementation获得数据需要通过两个步骤来实现。首先将data传给badi class,这些数据存储在这个方法的implementation的global attributes中,强烈建议在这个步骤提供sample code。通过badi中定义的mehtod来传递数据。然后存储在badi global attributes中的data就会被自动传到implementation的global attributes中,当然,implementation必须是active状态。使用的语句如下:CALL METHOD exit->put_data EXPORTING <data>.

l         在执行CALL SUBSCREEN语句之前,必须得到subscreen的screen number和program name,这个通过方法cl_exithandler=>get_prog_and_dynp_for_subsc来实现。如果没有active implementation,就会得到dummy function group(SAPLSEXM)的dummy subscreen (screen number 200)。如果存在active implementation,在implementation中指定的subscreen就会被使用。语句如下:CALL METHOD cl_exithandler=>get_prog_and_dynp_for_subscr EXPORTING … IMPORTING called_program = … called_dynpro = ..

l         调用相应的subscreen,如果没有active implementation,就会显示default empty subscreen。

l         如果在离开screen之后向得到Implementation中的data,则需要使用method:CALL METHOD exit->get_data IMPORTING <data>。

Implement badi screen enhancement的步骤如下:

l         创建badi的implementation指定包含subscreen的程序名和screen number

l         创建指定的program

l         Layout指定的subscreen

l         Implementing program必须得到badi的instance

l         从应用程序传递给badi的数据可以被取得。

l         如果想将修改后的数据返回给application program,需要调用相应的方法。

得到badi class instance的方法是CALL METHOD cl_exithandler=>get_instance_for_subscreens,这个reference是通过方法cl_exithandler=>set_instance_for_subscreen来传递的。这允许你在implementation中访问badi的attributes以及interface methods。Implementing program通过方法:exit->get_data IMPORTING <data>来获取badi中的data。通过方法exit1->put_data EXPORTING <data>将修改后的data传回给badi class的instance。

Filter type扩展性局限于以下几个方面:

l         Filter type参考的domain必须符合下面的几个条件:

Ø         Domain要指向cross client value table。这个value table只有一个使用的data element的domain是这个domain的key field。

Ø         Domain有一个两个key field的text table,一个key field使用的是这个domain本身,另一个key field是language field。其必须还得有一个text field,这个text field的类型为TEXT或TXT。在ABAP DICTIONARY中必须给text field指定一个value table。

Ø         这两个table的delivery class必须是E或S

如果没有active implementations,那么由enhancement provider提供的default implementation就会被执行。在badi definition中通过goto->default code就可以创建default implementation。还可以创建一个sample implementation。通过goto->sample code就可以创建。几种增强方法的比较:

 

Customer Exit

BTE

BADI

Source code

+

+

+

Menus

+

-

+

Screens

+

-

+

Table

+

-

[+]

Administration levels

+

-

+

reusable

-

+

+

Filter specific

-

+

+

BADI DEFINITION中的name conventions

l         Badi definition: <badi> or z<badi> or /../<badi>

l         Interface:IF_EX_<badi> or ZIF_EX_<badi> or /../IF_EX_<badi>

l         Methods:any name

l         Generated badi class(adapter class) cl_ex_<badi> or zcl_ex_<badi> or /../cl_ex_<badi>

BADI IMPLEMENTATION中的name conventions

l         BADI implementation <impl> or z<impl> or /../<impl>

l         Interface: IF_EX_<badi> or ZIF_EX_<badi> or /../IF_EX_<badi>

l         Methods:在badi definition中定义

l         Implementing class:CL_IM_<impl> ZCL_IM_<impl> /../CL_IM_<impl>

找到badi的方法:

l         在应用程序中搜索CL_EXITHANDLER

l         REPOSITORY INFORMATION SYSTEM

l         相关component的IMG

 

 

这哥们写的挺有建树,但是还是看不懂,不知道为嘛!

感觉到好自卑啊!太深了!

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值