ABAP Objects: Objects-Oriented Programming
I know what you are thinking. This fellow cannot spell (and maybe you are right, but that is another story). He even misspelled the title of this blog post!
Correct. I did misspell object-oriented programming, but it was on purpose. Being a native object-oriented developer, I have closely followed and actively participated in the tug a war between the ABAP traditionalists and ABAP objectists during the past +10 years. The more I read, the more I am getting convinced that it is not about being right. It is ABAP religion. Both parties have good intentions and there are pro and cons with both approaches. To make the best out of it, I believe you should embrace both and here some reasons why. I represent a typical SAP customer.
The reason I wrote objectS-oriented programming is simply that we rarely work on single objects in an enterprise computing context. Take for example Horst Keller‘s car example from his ABAP Objects bible. In SAP data processing it is not often you have the luxury of just speeding up one car. In the real world, an internal table is passed from a BAPI call or select statement with 20000 cars and they all need to change speed. It would be absolutely nonsense to convert the internal table into objects, speed up each car object, turning the objects into internal tables again, and finally passing them back to another BAPI call for persistence. However, I would create an object-based car class that contains car related methods. Especially I would focus on wrapping the BAPI calls into simplified customer specific methods so that other programmers would not need to re-investigate BAPI black boxes.
It is my impression that most custom ABAP developments are still based on BAPI calls or select statements for data handling. Both BAPI calls and select statements offer no object-oriented results by default. As long as it is that way, the benefit of ABAP Objects are mainly about having a more structured approach to your ABAP code and the advantages related hereto. The ABAP traditionalists would probably not agree. They claim that it is better to have everything in one place rather than spreading the code over multiple methods. In more object-oriented contexts such as for example Web Dynpro ABAP or CRM, the benefits of using ABAP Objects are more apparent. ABAP remains a hybrid language in the sense of sequential and object-oriented syntax. The question is therefore not about using ABAP Objects or not. It is about knowing where to use it and not. To do that, you must know both. Finding out how to best apply ABAP Objects is one of the most challenging tasks for ABAP developers. Seeing examples of how others have done this helps. I would greatly appreciate even more ABAP Objects stories on SCN.
The persistence classes are classic example of such misery. Even though we know there can be a completely OO access to the DB, we simply cannot use it. Persistence classes cannot cope with huge volume of data & that's what an ABAPer is expected to handle.
We thus have to resort to creating GETTERs/SETTERs methods wrapping the GET/SET BAPIs. These methods get "tightly" coupled to the callers and this kind of violates the Open-Close principle. So a cheeky OO developer will try to develop a solution based on RTTS which in most of the cases is not fool-proof 😉
So much for having a feature one cannot use in his daily coding 🙁
the list of OO compromises is rather extensive. Lack of ad hoc polymorphism is another one of them, although optional parameters partially helps to solve this issue.
One of the things that is way up on my ABAP Objects wishlist is also a true BC (Basis Components) and CA (Cross Application) API. Sometimes you find very useful functionality like for example the IF_RECA_MESSAGE_LIST, just to find out that it is not part of BW or GTS systems among others.
Thanks for pointing that out 🙂
And even though it is there(in ECC for example), developers are not aware of it 🙁 As a matter of fact i encountered it yesterday, we have a Z* logging class which is very similar to the IF_RECA*.
I wish it were moved to BC/CA namespace so that more people know about it.
And we come to point where great Z*API* is sometimes there, but other developers simply don't know about it. This shows how important is to share that info b/w teammates, otherwise even best reusable software becomes invisible = useless.
Nice to see you again in the forums, hope you reduce your PS time & get more into SCN 😛
Btw my point was different. I wanted to highlight that developers create custom APIs when there are standard ones available, why do you need to re-invent the wheel? No one's making the wheel square, isn't it?
Sure I do my best to cut off my PS time, but can't say whether I am back on SDN as active guy 😉
Anyhow I got the point and of course I agree with that. I just wanted to point that one may not only omit the standard approach, but may overlook the custom one too 🙂
I am enjoying your conversation. Both of you have valid points. Regarding ZAPIs, perhaps ABAP Doc will help getting an overview of custom libraries. It will be a part of SAP NetWeaver Application Server ABAP 7.4 SP 2.
Conversation with you guys is a pleasure even if we would argue 🙂
Didn't know about such planned built-in feature of ABAP, looking forward to putting hands on it. That would greatly help documenting available API and find easier standard libraries. I personally found such docs very useful i.e. for Java or SAPUI5. Playing a little bit with both these doc sites became my first browser's toolbar shortcuts.
While I agree that persistence classes are useless for large data volumes, they do have their place. I use them when I need to CRUD (Create, Read, Update, Delete) single or a few entries.
For example, I had the task a few years back to create a webservice for the creation of bespoke data - three or four main Z tables, plus a few others containing texts permitted values etc. All of these were to be created from another application, via the webservice.
For each table, I created a persistence class. Then I created what I call business object classes, implementing CRUD (I think is what Rich Heilman recommends), and bringing together some of the individual table entries (rather like "docno" "linno"). These were then called from RFC enabled function modules and a webservice generated.
Now - I could have done this without persistence classes, simply creating my own as it were, with selects and updates. But why bother? I only have to create the tables, and then generate the persistent layers. A bigger advantage though was the the business object classes were all pretty much the same in structure, which meant they were fast to develop.
The biggest advantage came when fields were added to the tables. To accomodate that, I simple added the field to the relevant table and structure, regenerated the persistent classes and made minor adjustments to the business object classes. The point is that the changes required were "obvious" and almost mechanical in implementation - meaning that the chances of error were much reduced.
I think that this hybrid nature of ABAP sometimes more disturbs than helps when it comes to OO development. This is especially seen when we type our methods' parameters. We will likely not create any wrappers around tables/structures which the method returns, as it would be cumbersome. In contrary, in JAVA all the data are objects (except plain types), so it is natual we work with i.e List which is an object for objects. This creates another trapdoor if one doesn't understand the concept how objects are spread accross application (and memory) and how they might be changed somewhere else. I run in such troubles serveral times because I lacked this true OO experience.
In ABAP we need to stretch our legs b/w procedural and OO approach.
Although I am a big fan of OO programming, I found it much simplier to do certain things with fast and dirty way if a deadline is approaching. Sadly most of ABAP developers I worked with prefer this style. I even found that even they have great domain knowledge, their programming skills are avarage (not to offense anyone). This results in building applications which will not survive a time trial, which I think is a factor of a good software.
sometimes I dream about SAP doing a Flappy Bird (read discontinue) to ABAP language dinosaurs. But then I wake up screaming when the backward compatibility monster appears, understanding that it is the uggly beauty of ABAP.
A main point with my blog post is that it is not about OO or not. Often I read blog posts about this is the way to do it and so on. However, it is rarely black or white. I would prefer more blog posts with this is our way of solving a particular issue. Leading by example that is. Lets get more examples out on SCN, it will surely open up a lot of discussions as people have different views on what is good implementation practice. But it will be fun - I think.
I totally agree. There is no one proper way of achieving one thing. And yes, example-driven discussion are more educational than just theoretical fight for preffered style. Recently I have heard one sentence which I truely agree with "an expert always considers a context before making a vote". So pretending to be one I will stay for your saying "let's get more examples out on SCN"... and discuss different programming styles in that specific context.
An important point when developing ABAP-OO is to recognise that, for example, an internal table is the equivalent of a Java int. I.e. we are supplied with a vast number of effectively basic, simple objects, whose handling is built into the language.
if you look at Keller's blog on 7.40 it seems that SAP are working on a spike in the ABAP language called NGAP (Next generation ABAP) which is not downwards compatible to the legacy ABAP stack - and hints at oo language improvements - and scrapping of many out of date features. If SAP truly break away from legacy compatibility in the future then hopefully we could see a cleaner form of object oriented programming - mind you its a big IF.
To quote from Keller here :
"In between, another ABAP code line was opened for SAP internal usage: ABAP 8.0 to 8.04 based on 7.2. This is the first ABAP code line ever, where ABAP was developed further in a non downward compatible way. In fact, many features that are regarded as obsolete have been removed from that code line (yes, even logical databases!). The new AS ABAP was made for NGAP (Next Generation ABAP Platform) and is used SAP internally for modern object oriented and framework based development of new products (e.g. Business by Design). Of course, legacy ABAP programs will hardly run on NGAP."
The only downside being that SAP are keeping it for internal use for now... Here's hoping it includes method overloading...
For most of SAP's ABAP based products (ERP, ...) and customers it is the left hand side of the figure in ABAP News for Release 7.40 - What is ABAP 7.40? that counts.The rigtht hand side (8.0x-line) was done for internal use only and currently is not developed further. Even there, we could not get rid of all that obsolete stuff, e.g. header lines of internal tables. Why? Because SAP Basis itself (Workbench, Admin Tools, ...) is using too much of it in its legacy code (who should refactor all that stuff?).
Currently, all ABAP development efforts go into 7.40. And there, you have the "backward compatibility monster" in full blossom (development in SPs!). That means, in 7.40 you can happily mix awkward old R2 style with modern functional style, e.g.
These three lines are syntactically correct, but simply don't do it ...
OK, OK, I know how idealistic this is.
I have a dream of a "new flag" for ABAP programs that includes the existing unicode flag and the fixpoint flag and that extends the stricter syntax rules of classes (and from release to release some more strictness) to all parts of a program. New features of the ABAP language would be available only in programs that have the "new flag" switched on. That would avoid the mixing of new and obsolete features. Legacy programs wouldn't have the "new flag" and could rest in peace.
Only a dream. Introduction and maintenance of such a flag into the existing infrastructure is not feasible. Only in a part of the language an implicit kind of the "new flag" appears: In Open SQL the usage of new features that are introduced with 7.40, SP05 and later will automatically switch the full statement to "new syntax", where you have to follow stricter rules (you must use comma separated lists, you must escape host variables, some warnings become errors). At least a little bit of education but maybe also somewhat surprising from case to case.
Thanks Horst for clearing that up! I would definitely be in favour of the flag solution!
I was kinda hoping that 8.0 would solve all of our problems, but I get it now - internal use only (it was the next generation title that had me going...). At our site we are about to upgrade to 7.40 (starting next week) so really looking forward to all of the new features that you have been blogging about.
Tarzan want flag 🙂
ok I see we will not get such a flag soon. For me working as quality engineer it would have been a great option to enforce this flag for all new developments.
What about a pragma / pseudo comment to tell the ATC / SCI to be more strict? This would be a little more gentil?
An other great option would be to enhance the syntax highlighting as we know from other IDEs that paint warnings if you use deprecated stuff,so that we show all these developers with lots of experience "Hey! there are "new" ways!" Could that be an Option?
Yep, some years ago we had all these plans.
I dreamt of a Quality Cockpit, where a Q-Manager could adjust different quality checks with a kind of rulers from lax to strict ...
Yeah, I always favorized an awful brown for awful code ...
But alas, the Code-quality initiative didn't develop too much drive. In fact, its only a book that is leftover from that phase and meanwhile we have so many other things to do (e.g. ABAP documentation, I have to write and write and write and write ... ).
You have to write and write... but it seems so few bother reading... 😉
Maybe there should be a "read ABAP docu"-mission here on SCN 🙂
That mission would be never-ending.
I'd like missions such as
"Promoted the use of ABAP Objects as a programming paradigm."
"Persuaded a developer of the benefits of OO"
"Persuaded an ABAP developer to learn JAVA in order to better appreciate OO".
In order to do so, citing advantages and debating may not be enough.
The person would have to first build trust and gradually showcase the advantages.
There was a quote from Hannibal TV series about psychic driving.
The subject pushes back when he suspects that he is being pushed.
Key is that the subject must not be aware of any influence.
Here's a story. I needed to do a lot of work with user accounts (at an individual level). So I created a ZCL_USER class. This uses BAPIs to read and write the data, but it's all encapsulated within methods. The key point though is that I can say e.g. "user->add_role( role )", which is then recorded, but it's not until I go user->save( ) that the BAPI for updating the database is called.
In this way, I've removed all the messiness of the BAPI interfaces, and now have simple methods like:add_role, set_type, set_address etc.
Now, if I needed to handle these things in bulk, the trick would be to create a ZCL_USERS class. This probably wont' use the ZCL_USER class directly to do reading and updates - that would be too inefficient to do in bulk, but it would all the user of the class to get ZCL_USER objects. The point here is that the implementation for the user of the class is irrelevant - you can put select * into table if you want - but you can still retain a sensible object model.