Skip to Content
Technical Articles

ABAP-Types with class

An application has its types: table types, structures, even types for references to classes may be useful. In order to make types accessible to all classes of our application, it’s obvious that they should go to a central point, which could be a class or an interface.

I personally prefer a class for types, because an interface has a different usage: it is made for being implemented by another class. Types are only declarations that should be available from different classes. But all what I am going to talk about works for interfaces and classes as well.

So we start our application in our brand new packet, let’s name it ZAPP.

The types class

class zcl_app_types definition.
  public section.
    types awesome_data_line type some_structure_from_ddic.
    types awesome_data_lines type standard table of awesome_data_line with empty key.
endclass.

Now we are ready to use it:

class zcl_app_backend definition.
  public section.
    methods do_the_magic_on_table
     importing data_line type zcl_app_types=>awesome_data_lines.
    
    methods do_the_magic_on_line
      importing data_line type zcl_app_types=>awesome_data_line.

  private section.
    data awesome_data_lines type zcl_app_types=>awesome_data_lines.
endclass.

Use a shorter alias for the type class

But how can we make it slimmer? It’s pretty noisy having always the ZCL_APP_TYPES as a prefix for each type. In real live, the name may be much longer (real live example: ZCL_MM00_PURCH_HISTORY_TYPES). With interfaces, we could use aliases to map types to local names. But this means creating a new alias for each new type of the local class which is quite noisy too.

With a type class, we can do a mapping with a simple trick: creating a data object with reference to the class. The data object offers all public static elements such as types. Using this, the class transforms like this:

class zcl_app_backend definition.

public section.
  data types type ref to ZCL_APP_TYPES.

  methods do_the_magic_on_table
    importing data_line type types->awesome_data_lines.

  methods do_the_magic_on_line
    importing data_line type types->awesome_data_line.

private section.
  data awesome_data_lines type types->awesome_data_lines.
endclass.

 

Types from other APIs

Now we have types-> as a prefix for all types of out application-own types class. When we use types from other API applications, the name extends a bit:

data common_types type ref to zcl_abap_common_types.
...
methods get_binary_lines
  returning(result) type common_types->ty_binary_lines.

 

When use types classes

I personally keep all types that are used in more than one class in my types class. In other words: no public types if not in the type class. However, there are always exceptions to the rule. In DB_ACCESS classes that are intended to only transfer data from the data base to the application, I sometimes define my result table directly in the interface:

interface zif_app_db_access.

  types settings type standard table of zdb_pp01_001 with empty key.

  methods read_settings
    returning(result) type settings.

This is OK for me as long as I never see

type zif_app_db_access=>settings

in my code. As soon a the type is needed in other classes than the DB_ACCESS class, I would transfer it to zcl_app_types.

Where is the benefit?

To me, it is very simple to just use types-> to have access to the types that my app is using. Using the editor’s code completion I can see directly every type already available. Since every type is in one class, no ambiguous names occur. (think of zif_db_access=>ty_data, zcl_app_backend=>ty_data…). Distinguishing between types and variables is also easier for the types look always like type->data_lines while the variable appears as data_lines only.

The shorter naming extends also legibility because code lines are kept shorter. Each set of types can have a clear name that replaces the global name of the class.

13 Comments
You must be Logged on to comment or reply to a post.
  • Hi Jörg,

    I personally use a lot the types declaration within a class but I have to disagree with you on one point: “When use types classes – I personally keep all types that are used in more than one class in my types class”.

    If you need to use the same type in more than one place, I would always suggest creating it in SE11.

     

    Cheers,

    André

     

     

    • To me, a DDIC type is useful when using it in user interaction. Otherwise defining texts for labels in different sizes and languages seems needless to me. I prefer to define types that serve for program logic and not for user interaction directly in ABAP code. This is also less time-consuming.

      • I agree with this philosophy. If it’s a purely “technical” type, i.e. we don’t need any semantic definitions and don’t plan taking advantage of anything associated with dictionary types (i.e. it won’t be anything user-facing or used in a service definition that can be generated, and such) then there seems to be no advantage in using dictionary. Granted, SE11 has better “discoverability” but it also means it can easily become polluted, especially when similarly named elements are used in different contexts with different definitions.

        It’s all about the use case, plain put.

        Thanks for the blog!

        • what is the difference between DDIC-structure and public type of interface?

          in both cases it is in server memory, but in DDIC it is more manageable and clear to check and compare.

    • I guess one argument in favor of defining a type in the DDIC is to avoid having errors during the transport of repository objects, by transporting the DDIC objects first in a dedicated request (as far as a DDIC type does not refer to a class or an interface…)

      But there is the Transport Check tool to avoid those errors too…

  • I think for NetWeaver is not the best option to use types in class. DDIC is the more preferable.

    The main reason: when the types in class or interface is changing , the program where it is used is  forced to regenerate and it could cause the syntax errors (LOAD_PROGRAMM_MISMATCH) during the transporting.

    Another option is DTO (but it is differ from types).

      • DTO on wiki

         

        Data Transfer Object sample:

        CLASS zcl_order_conf_dto DEFINITION
          PUBLIC
          FINAL
          CREATE PUBLIC .
        
          PUBLIC SECTION.
            DATA mv_kunnr TYPE kunnr READ-ONLY.
        
            METHODS set_customer
              IMPORTING iv TYPE kunnr.
        
            METHODS set_any_other_field
              IMPORTING ivr TYPE REF TO char10.
        
            METHODS get_any_other_field
              RETURNING VALUE(rv) TYPE REF TO char10.
        
          PROTECTED SECTION.
          PRIVATE SECTION.
            DATA mv_any_other_field TYPE REF TO char10.
        
        ENDCLASS.
        
        
        
        CLASS zcl_order_conf_dto IMPLEMENTATION.
          METHOD set_customer.
            mv_kunnr = iv.
          ENDMETHOD.
        
          METHOD set_any_other_field.
            mv_any_other_field = ivr.
          ENDMETHOD.
        
          METHOD get_any_other_field.
            rv = mv_any_other_field.
          ENDMETHOD.
        
        ENDCLASS.

         

         

         

    • Sincerely I do not get your point Wouldn’t a change of a ddic type also cause a regeneration of the program? Whether you have types in DDIC or a class, the repo objects must be always aligned  before running the program.

      In case of a type class with 100 types you have one repo object to align. When each type is in ddic you have 100 repo objects to align. I prefer the first one.

      • in case class will be used in several reports/classes/functions – all this functions would be regenerated even if you change .

        in case you have 100 separate objects – small change will cause regeneration only where exactly it  one changed object is used.

        For global types abap_help mostly tells us that declaration is up to context, but provide recommendation about separation of concerns and semantics meaning.

        ABAP declaration

         

        • I understand the point. But I do not see the disadvantage – when a change comes with transport order, why should i be concerned whether 10 or 40 programs are regenerated?

          As described above, the type classes are application-exclusive. So the where-used lists of them are not too big.

          Another thing is the name: a ddic type can have a 30 character name. Depending on your naming conventions (or even worse a name space) few space may remain for a clear and descriptive name.

          Having the type in a class, you can use all of the 30 characters available to the name. Since the type class is application-exclusive, no prefixes or namespaces are needed.

           

          • But I do not see the disadvantage – when a change comes with transport order, why should i be concerned whether 10 or 40 programs are regenerated?

            yes, you are correct. it depends on the situation. And sometimes we should not care about this. Agree. But sometimes we should.

            Having the type in a class, you can use all of the 30 characters available to the name. Since the type class is application-exclusive, no prefixes or namespaces are needed.

            🙂 However in DDIC I could put also documentation and make reference to data element.

             

            PS. Actually I am using both types in class/interface and DDIC and agree with you point but trying to provide another approach.

            Mostly I am using types in class + DTO and it provides more semantic information for code understanding.