Before Matthew Billingham will tear out my poor head and impale it on the walls of Join Castle as warning for the future generations of fools, please try to follow the White Rabbit down the hole as I try to explain why I think so. ๐Ÿ™‚

First of all, which is the main feature of OOP? Well, obviously is to identify and manage all the components of a report/procedure/flow as stand alone objects which can inteact each others via some public methods and can be identified by public attributes (I put it down pretty simple and somehow semplicistic, I know).

So, take as an example an easy and quick report required last week to be develop: extract all the materials open in a set of storage locations and retrieve the last material movement for that material-storage location (inbound or outbound do not count).
The user then can select one or more records and create a corrective movement for specific situation.

It’s nothing too complicated and we can start to check out which are the objects we need.

The first one is obviously my APPLICATION with the report bones and structure then I can see the MATERIAL with all the logic to retrieve materials’ data. As third step, we have MATERIAL DOCUMENT to get the last material document and to manage the new one. And finally our ALV to show data and manage user interaction.

Easy task, quick report but 4 objects.

I do not want to bother with a detailed explain about the report but I want to focus on the interaction bewteen MATERIAL and MATERIAL DOCUMENT (from now only MDOC).

Now that I got my objects to manage, I sink a bit deeper in them and I find out that MATERIAL is used just to retrieve data and do some check (like authorization ones on plant).

So my methods will be

  •   GET_DATA (public, export a table with all the materials-description-plants-s.locations-qty)
  •   GET_MATERIALS (private, fill main table from marc-mard)
  •   FILTER_AUTH (private, filter retrieved data with auth check on plant)
  •   SET_DESCRIPTION(private, retrieve material description)

As you can see, I kept SET_DESCRIPTION separated because if GET_MATERIALS can be easly implemented with a join, my descriptions are language dependant and I had to do a double read based first on SY-LANGU and then with english (company default).

At this point I’m forced to use FOR ALL ENTRIES based of the result of the join between MARC-MARD.

But even if I manage to extract a bunch of useless records putting in join MAKT wihout the language filter and then skim out the result from my internal table, I just got half of the informations I need.

And here the MDOC enters in play.

MDOC will have the following methods:

  •   GET_LAST_MDOC
  •   <methods for the building and calling for BAPI_GOODSMVT_CREATE>

I want to focus on GET_LAST_MDOC.

So, i got my array of materials and for each one I have to retrieve last material document and, being them 2 different objects, I cannot create any join.

So i got 2 options:

LOOP my materials, for each one retrieve the data with a bunch of selects.

Or i can use FAE, retrieve all data at start and then work with internal tables

Surely, it’s a report, i can throw away the OOPs and put all in a join together but then? OOPs helps alot in organizing the code, identify the issues/objects to be threaten and I like the idea I’m building a forma mentis.


I know,  FAE are deprecated and should be replaced by JOINS but… YOU CANNOT DO IT if you are going to use OOP!

How can you improve performances and void the bad guy (FAE) when you work with objects?

The power of objects is that you virtually can develop them stand alone and only later you can mix and merge them in your process/development.

And in my opinion FAE becomes quickly the only option you have to avoid the even more deprecated SELECT in LOOP

Now, Matthew, you can have my head ๐Ÿ˜‰

A little note-add:

Pointing out my failures and faults is really appreciated: I believe in constant learning so if I can improve exploiting the SCN work and experience and knowledge, why not? ๐Ÿ˜€

To report this post you need to login first.

28 Comments

You must be Logged on to comment or reply to a post.

  1. Tomas Buryanek

    IMHO OOP does not require FAE, but design might (or might not) require FAE.

    It does not mean you have two objects if you put selection into two different methods and internal tables. That is more like separation of concern (SoC).

    For this example of small report it is maybe too big separation? But if it is just example, then yes, FAE can be usefull for joining two sets of data. Why not, if design needs it separated?

    For multiple material texts? ๐Ÿ™‚

    SELECT mara~matnr

       makt1~maktx AS maktx1

       makt2~maktx AS maktx2

       makt3~maktx AS maktx3

       FROM mara

       LEFT JOIN makt AS makt1 ON ( makt1~matnr = mara~matnr AND

                                                        makt1~spras = ‘CS’ )

       LEFT JOIN makt AS makt2 ON ( makt2~matnr = mara~matnr AND

                                                        makt2~spras = ‘EN’ )

       LEFT JOIN makt AS makt3 ON ( makt3~matnr = mara~matnr AND

                                                        makt3~spras = ‘DE’ )

    (0) 
    1. Simone Milesi Post author

      Hi Thomas,

      IMHO OOP does not require FAE, but design might (or might not) require FAE.

      Right, you hit the nail explaining better what I mean: if you are designing something using objects, FAE can be required.

      Sounds better?

      Surely I used a small report with a strong separation, an excessive one if you want to see it.
      But as I stated, I want to build a way to think which become pretty automatic and using it even in this kind of small reports helps me alot ๐Ÿ™‚

      But if it is just example, then yes, FAE can be usefull for joining two sets of data. Why not, if design needs it separated?

      ROE point 3 How to get your post rejected in ABAP Development

      There is a reason for me tagging Matthew as first thing ๐Ÿ˜€

      And for the selection: why should i extract more data than what i need? I need description in SY-LANGU and only if not exist, in EN.

      It seems a bit too… useless that kind of approach.

      (0) 
      1. Tomas Buryanek

        For selection: In this case I would not be afraid of performance decrease, since it is access by primary key and only one additional field.

        But you are right it is selecting unnecessary data. For avoiding it you can use just one join for getting SY-LANGU MAKTX, and after that try get the other language but just for entries without MAKTX. But that would be probably with FAE, and all together might have worse or around the same performance like that double LEFT JOIN MAKT? Would be interesting test and measure something like this ๐Ÿ™‚

        (0) 
  2. Matthew Billingham

    Just a couple of points.

    1. FAE is not deprecated. In BI/BW it is often a necessity. FAE is very useful when you are supplied with data in an internal table. Perhaps after a FM call, for example, or in a user exit.

    2. Pure OOPs (in my opinion – others disagree) is not a good way to develop reports in ABAP which typically rely on bulk read operations. If you’re going to program in ABAP Objects you need to take a pragmatic approach – don’t use persistence classes for bulk reads, don’t objectify internal tables.  I only use the persistence framework when I’m dealing with single records (or a handful).

    : if you are designing something using objects, FAE can be required.

    Sounds better?

    For your program wouldn’t question the use of FAE as such, I’d question using a programming structure that required the use of FAE. In OO philosophy, you’ve done the right thing, but in ABAP Objects philosopy – it’s bad programming. I.e. if you are designing something using objects and you find FAE is required – your design is smelly! https://en.wikipedia.org/wiki/Code_smell

    If the separation of concerns requires a split (which in my 15 years of ABAP Objects has never happened), then of course FAE is the way to go. See point 1.

    (0) 
    1. Simone Milesi Post author

      Thanks for joining Matthew, I was really hoping for your opinion and I hope you do not mind the little joke ๐Ÿ™‚ .

      You say OOP is not good in local object but also SAP says that FORMS are obsolete so, what a poor developer can do? Just replace FORM with METHOD? Seems a bit…. silly to me.

      For this I try to push things on the hard side of OO.

      It’s also true that often, at least to me, the difference between OOP and ABAP Objects is so fleeting that boundaries blur.

      (0) 
      1. Matthew Billingham

        Simone Milesi wrote:

        Thanks for joining Matthew, I was really hoping for your opinion and I hope you do not mind the little joke ๐Ÿ™‚ .

        You say OOP is not good in local object

        No. What I say is that OO principles can get in the way of good programming.

        You as the developer choose your level of object granularity. Because of the way SAP works, this is probably at a higher level than a Java programmer would be used to. So select all your data in one database hit to ensure you don’t have performance issues. Have a single class materials.

        Be pragmatic. Using FAE because OO requires it, is not pragmatic.

        OOP only requires FAE if you “objectify” at a low level. Which is probably too low a level for decent ABAP Objects programming.

        (0) 
        1. Simone Milesi Post author

          But it’s not logic, for my point of view splitting the Material Document object between materials (for data extraction) and MDoc for creating a new Material Document.

          Why? Material Document is always material document.

          I surely give another read to good old BC401 but still I feel that I’m missing something, maybe just a lack of pragmatism.

          (0) 
          1. Jacques Nomssi

            Hello Simone,

            I will refer to Eric Evans (Maintaining Model Integrity – Bounded Context):

            Explicitely define the context within which a model applies. Keep the model strictly consistent within its context, don’t be distracted or confused by issues outside.

            I think your FAE usage is necessary to translate from the context of the material master tables to the context of your model. Your model is potent in the context of your report/application, but it is not applicable to the schema of the material master.

            This an issue outside the model you created. Multiple models are in play on any large project.

            hope this helps,

            JNN

            (0) 
            1. Simone Milesi Post author

              Hi Jacques ๐Ÿ™‚
              I posted this just to collect some feedback/impression/opinions from the community since even if i use FAE i’m pretty satisfied with my report’s performances and structure.

              I’m an hot, hard head which sometime needs to think over and over and over the things before mend with them ๐Ÿ™‚
              And you gave some nice hints (as well Matthew and the others)….along with something more to think over and over ๐Ÿ˜€

              Thanks all for your suggestions and opinions ๐Ÿ™‚

              (0) 
  3. Naimesh Patel

    But what about the tables which can’t be used in the JOIN – like BSEG – A big giant cluster table?

    Also, where did you read this?

    I know,  FAE are deprecated and should be replaced by JOINS but… YOU CANNOT DO IT if you are going to use OOP!

    For performance intensive programs – Even SAP supports suggested to replace the JOIN and use FAE in Data services programs generated by Business Objects.

    Is there any different programming related to data selection when working with OO?

    Regards,

    Naimesh Patel

    (0) 
    1. Matthew Billingham

      Cluster tables are being phased out, and can already be converted to transparent tables. I seem to recall (I could be wrong) that there are no cluster tables with HANA…

      Data Services, which I’ve had the dubious pleasure of encountering a number of times over the years – even before SAP bought out BO who bought out the original – generates dogs’ breakfasts of code, and in my view shouldn’t ever be held up as an example. (It’s not just Data Services, any form of computer generated high level code tends to be appalling. I remember a product that generated COBOL for mainframes, that had a “gui” interface for designing the applications, heralding “the end of programming”… total disaster!)

      Anyway – the thrust of my famous blog is very simple. It doesn’t say “never use FAE”, it simply says that using FAE is rarely more efficient than using a JOIN. This was in the face of a widespread myth that FAE was always better than JOINs, and you should never use JOINS for that reason. Which is utter utter bilge.

      (0) 
      1. Naimesh Patel

        Data services may not be a good example, the but customer use those type of tools (and a matter of fact the query builder as well) and end up running to lot of performance issues. My point was that even SAP support (not sure what level of that would be) suggest to copy the generated program into custom program and replace the Join with FAE.

        And overall program performance using FAE has better performance than join. Because the way data would be sent into Output. Within JOIN the “Header” would be repeating for each detail row. It would be additional cost, to only keep unique header rows. This cost would be huge when you have hundreds item for same header.

        I agree with the last statement on your post – maybe compare runtimes if in doubt.

        And this must not be only specific select query, but entire process (or program).

        Regards,

        Naimesh Patel

        (0) 
        1. Thomas Zloch

          That discussion took place in 2008, I had used joins five, six years by then, and happily ever after. Whenever I can that is, the few exceptions are handled by FAE, which is also a very welcome construct, or sometimes sub-queries.

          I keep repeating the major advantages of joins from my point of view:

          – CBO can flexibly choose the best access path based on actually provided selection criteria

          – the result is in one internal table right away, perfect for ALV grid output and many other purposes

          I have yet to see a noticable impact of the redundant header data, maybe if dozens of header fields are repeated hundreds or thousands of times, I don’t know.

          Pretty much what I said here, for example:

          inner join vs for all entries | SCN

          Joins for president. ๐Ÿ™‚

          Thomas

          (0) 
        2. Matthew Billingham

          I’m sorry Naimesh, I’ve a lot of respect for your knowledge and understanding, but you are completely out on this one. The programs have been written, the tests have been done.

          In most cases: replacing a JOIN with FAE will produce worse performance. Fact.

          As far as SAP Support proposing it – I’ve been using SAP Support since 1997, and dealt with many performance issues. I’ve never been advised to use FAE over a Join, I’ve never seen a note proposing it. Furthermore, I’ve often replaced FAE with a JOIN and seen good results.

          Also, for your consideration, think about the fact that FAE has huge potential to completely screw up selects from HANA. (Hence the requirement to either remove them, or add hints). I know it’s a fact for two reasons:

          1. I’ve been through a few HANA conversions and one of the important tasks was replacing previously perfectly function FAEs with Joins (or adding Hints where unavoidable)

          2. I’ve had it confirmed by HANA/ABAP experts. I even got one of them to change their slides where the wording might have promoted FAE.

          (1) 
          1. Naimesh Patel

            Hey Matt, glad to know that I’m in the inner circle ๐Ÿ™‚

            I can’t find the message where support suggested to try with FAE instead of Join. I will keep looking and see if I can find that communication.

            I know that I will not be able to convince you at all for any plus point of using the FAE. I recall one more incident where customer had lot of performance issue in Search Help. That SH was using about 7 different tables (DB View > Used in SH). After analyzing the trace, I removed one table from the mix, replaced with FAE and Surprisingly performance was 95% improved. I agree that it will not be case always. Thus trace would be an important tool to see if divide and concur would work.

            I don’t have much experience on working with HANA DB yet, so I can’t comment but would need to learn so I can get my facts straight.

            Thanks,
            Naimesh Patel

            (1) 
  4. Jelena Perfiljeva

    20 comments and just 2 likes and 2 ratings? Hmmm…

    I’m guessing the low ratings are a form of disapproval of the chosen design. But these are valid questions to ask and valid doubts to have, expressed in a more intelligent way than many other blogs here.

    +1 to Matthew’s comments – such granularity is simply not practical here. Heck, many ABAPers would just get it done using 3 routines. ๐Ÿ™‚

    (0) 
  5. David Henn

    Hi,

    I think you could just separate the data retrieval and the object logic.

    First query your DB with all the performance of joins.. etc and then create objects for the results.

    We normally pass a structure with all the data for an object via the constructor to the object.

    Normally we do this in a factory

    Maybe this example of a factory method right out of our codebase helps to clearify my points:

        DATA t_material TYPE /cenitapm/owmaterial_tt.

        DATA s_material TYPE /cenitapm/owmaterial_st.

        DATA o_material TYPE REF TO /cenitapm/cl_ow_mat_ap.

        DATA o_db TYPE REF TO /cenitapm/if_ow_db.

        o_db = /cenitapm/cl_db=>get_instance( ).

        t_material = o_db->get_materials( i_process_guid ).

        LOOP AT t_material INTO s_material.

          CREATE OBJECT o_material

            EXPORTING         

              i_logger              = me->o_logger

              i_mat_st              = s_material.

          o_material->init( ).

          APPEND o_material TO r_value.

        ENDLOOP.

    (0) 

Leave a Reply