Does OOP require FAE?
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? ๐
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? ๐
Hi Tomas,
Can we not use the languange(SPRAS) in the WHERE clause? E.g.,
This will return multiple lines instead of multiple fields in one line of result. And you can not use left join if you put condition of MAKT table to WHERE.
With the where clause it's not the case with new releases anymore ๐ Which I very like!
I am working on a ABAP 740 SP12 system and i am luvin' it 😘
Only 731 here, yet ๐
Sorry, did not see the LEFT JOIN! My bad 😏
Hi Thomas,
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 ๐
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.
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 ๐
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).
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.
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.
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.
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.
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
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 ๐
Maybe the new GTT (ABAP News for Release 7.50 - INSERT FROM Subquery and GTTs ) will come to rescue?
From performance perspective, not OOP encapsulation.
I think this is a form of the Object Relational Impedance Mismatch.
JNN.
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?
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
From my previous link in comments
For All Entries is NOT better than INNER JOIN in most cases
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.
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
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
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.
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
I don't know the exact case, but it sounds like a good candidate for DB hints (instead of FAE).
If you need to use FAE, then please study the various notes about using hints with them, especially with HANA. 2142945
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. ๐
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.
Revisiting this blog, I think the issue here is that you're getting bogged down in ABAP language specifics. You would have exactly the same issue if you were writing your program in Java.
In Java, you'd be issuing the SQL directly to the database. You've two choices.
If 1 isn't performant, do 2. Actually - do 2 unless you really need to keep the materials object separate from the documents object.
Similarly with ABAP, except option 1 is FAE.
This is not an OO versus non-OO issue.
Oh my!
i had to re-read my whole blog to remember what i got in mind... and i'm not sure about it! ๐
But i never said this was about OOP vs not OOP, not at all.
It was a doubt about FAE and if it was a "forced choice" in OOP.
You speak about Java and Javaย theorically should be designed with an high granularity (i retrieved my school books about this, maybe in 20 years things changed ) so solution 1 should be the preferred one.
Honestly, in past two years i used FAE where i felt i need it (i.e. keeping things pretty separated or JOIN not possible) and JOIN whenever my design would allow and i could use it (PUT DOWN THE PIKE!).
When during the tests i see the performances are impacted by a mere 3-5% (thumb rule), i prefer a slimmer and more "granular" design because it allows me to understand after a month what i was doing and to add or remove pieces more easily (working a lot with gateway and OData services, i often face this kind of need).
Fair enough.
With Java you're forced to high granularity in many ways because the base language is not rich - unlike ABAP. But there's no-one forcing you to divide up database objects, for example.
There's always tensions in any language. In db design, everything "should" be normalised. But for performance reasons, we denormalise. What matters is that the program is a cheap as possible to change/enhance (which means "well written") and that it does it's job.
Your approach to design works. (Maybe you could write it up - I'm just starting to work with OData services regularly - i could do with some hints on a good approach).
My beef has always been against those who say you should always use FAE and never user JOINS. It's fact that most of the time JOINs are better performing. It's my opinion that JOINs make for neater code.
But on top of that, pragmatism rules.I leave philosophy to those in their ivory towers. ๐
Oh, made a little recap of that momentum in which i wrote this blog: there was this kind of discussion about FAE vs JOIN and i was drastically changing my design style from old FORMS (customer with heavy payload of 20+ years of developments) to new OOP (new job, with virgin system).
So i was full of doubts and pulled your leg, remembering the 30+ pages discussion on the old SCN about the topic ๐
The first reason i see to use FAE in a OOP/Gateway contest is when you have entities you can retrieve/handle both alone and in deep entity: a common method, called in 2 different places.
i'm still working my mind around this and i'm still changing my way to manage all of this.
PS (i'd love to edit my previous comment, but it keeps saying i'm not logged in)
Why resurrecting such old blog?
Why not? ๐