Etiqueta > OO
Supported by

Clean ABAP

For many years, when confronted with ABAP OO, most ABAPers I talked to, acknowledged that OO is great for most languages but never saw any real advantage in adopting it for ABAP. So they carry on using FORMs, INCLUDEs and CALL FUNCTIONs. The standard SAP code sets the example by trying to make something work while breaking every possible programming best practice.

Ler o resto do artigo! »

Serialization – Clone Dolly in ABAP

A ovelha Dolly

This article was written by José Vília:

The Dolly sheep was alive in ABAP and I didn’t know about it.

Having created a class instance, I’d like to share it with another totally independent program to use it as if the instance had been created there.

It’s an ABAP Dolly sheep factory we’re talking about here, people. Serialization in the ABAP world.

Ler o resto do artigo! »

Get the deepest text of chained exceptions

If you’re not already using ABAP Objects you’re chicken.

If you use them, I do hope you’re following the best practice of using class exceptions.

And if you’re using class exceptions you better understand the best way of using them, particularly the advantages of chaining them.

This said, here’s what brings us here today. In the post about chained exceptions I showed a way to get the text of the deepest exception in the chain by using a WHILE loop:

Ler o resto do artigo! »

Convert class exception to BAPIRET2

Some time ago I wrote an article explaining a way to automatically convert classic exceptions to exception classes. Today I use this technique in almost all the exception classes that I create (and I’ve even improved it, but I’ll leave that for another post).

This tip explains the exact opposite.

Ler o resto do artigo! »

Software design patterns in ABAP

We are constantly learning. But once in a while we learn something which is a leap forward forcing us to look in a new way to everything we do.

The last time this had happened was when I started using OO in ABAP. OO was not new to me as I had already used it extensively in Java, C#, C++, etc. But to finally be able to apply these precious concepts on my daily job was a relief and a big improvement in the quality, flexibility and speed of my work.

I feel now in the middle of a new leap forward. Because I’m finally learning how to use software design patterns. I’ve always heard about them but never gave them much though. For example, the ABAP site ZEVOLVING already talked about them a long time ago and I remember having read many of these articles. But somehow I still hadn’t found a text which not only explains them but also makes their advantages clear.

Now, thanks to Miguel Jorge, I have found one:: Head First Design Patterns. Besides being funny, it explains in a clear and simple way, the limitations of OO paradigms and how patterns can help overcome them.

This site has links to several interesting texts on this subject. It even has a link to a PDF version of the aforementioned book. And also to this page which lists them and even criticizes them.

From now on, whenever I’m designing software in OO I’ll always try to be aware of the available patterns and try to apply them whenever appropriate.

Thank you Miguel Jorge!

Greetings from Abapinho.

Converting an exception into an exception

If you’re still not using exception classes, then you’re making a mistake. Cause they are very healthy for your code. They’re not only good nutrients for the system, they also make it lean and less vulnerable to diseases.

There are cases where you still need to deal with the old exceptions. For example, when a function module is invoked.

In this article I am presenting a suggestion that seems a little complex, but it works very well if you need to integrate the old exceptions with exception class in a simple way. And though it is sophisticated, you only need to do it once. Once it’s done, it’s easy to use.

Ler o resto do artigo! »

Chained exceptions

Today I will teach you how to chain exceptions. It’s a very practical solution to a complicated, not so obvious problem.

Let’s start by describing the problem.

Imagine you are in the application BANANA.
The application is quite complex.
It has three modules: BANANA1, BANANA2 and BANANA3.
Each one has its exception class ZCX_BANANA1, ZCX_BANANA2 and ZCX_BANANA3.
Since the application is in fact well designed, all the exception classes inherit from the same ZCX_BANANA.
Now imagine the following scenario.
You are in the BANANA1 module doing something.
There, you must call a class from the MORANGO module.
Of course, this class launches exceptions of the type ZCX_MORANGO.
This is the context.

You have several options:

Option 1: Declare the external exceptions
The method which calls the MORANGO class declares the exception ZCX_MORANGO in RAISING.
All of the methods which call it must declare it as well.
Henceforth, to the top of the call hierarchy.
It’s a big mess.
Imagine that BANANA must also use classes from the modules ABACATE, LARANJA and UVA.
It will also have to declare the respective exception classes in every method which uses them.
The more complex it is, the more confusing it all becomes.
This is not what we want.
Generally, anyone who does this ends up having to do a CATCH CX_ROOT, which is somewhat unhealthy.
For all of these reasons, option 1 should be avoided.
Except in very simple scenarios.

Option 2: Convert external into internal exceptions
Each BANANA method which invokes MORANGO methods always does TRY CATCH for ZCX_MORANGO and immediately launches an exception of the type ZCX_BANANA.
This even works.
The problem is that, for each exception of MORANGO, there must be an equivalent exception of BANANA.
If it’s just one, everything’s okay.
But in the case of dozens, it becomes silly.
And it’s not very secure.
Each of the exceptions created will have to replicate the specific text of the respective MORANGO exception.
This is not very practical.
This is because if tomorrow someone changes something in MORANGO, then BANANA becomes outdated.
It also tends to generate a large amount of confusion.
For all of these reasons, option 2 should be avoided.
Except in very simple scenarios.

Option 3: Use PREVIOUS to create chained exception
All exception classes have an attribute called PREVIOUS.
This is a reference for each exception class.
When the BANANA method invokes methods of MORANGO it always does TRY CATCH to ZCX_MORANGO.
But it does not launch a specific exception for each exception of MORANGO.
Instead, it always launches the same ZCX_BANANA exception.
But I have assigned the MORANGO exception to the PREVIOUS of the BANANA exception.
Whoever handles all the exceptions at a higher level only has to see whether the PREVIOUS has any content.
If it does, then it presents/saves/processes the exception there as well.
Ideally this should be done in LOOP.
In the event the exception of PREVIOUS has, in turn, another exception in its own PREVIOUS.
This is the best of both worlds:
Future proof code, which does not lose the information of specific exceptions.
For me, this is the best option.

I hope the both problem and the solution I propose are clear.

I leave you now with a simplified implementation of option 3:

    CATCH cx_morango INTO o_exp.
      RAISE EXCEPTION TYPE cx_banana
          previous = o_exp.
CATCH cx_banana INTO o_exp.
    log( o_exp ).
    o_exp = o_exp->previous.

Thank you Clark for the photo.

Greetings from Abapinho.
Ler o resto do artigo! »

Best practices
Thou shalt use use exception classes

In classes, consider using exceptions classes over the old ones. These have great advantages and, once understood, are simple and allow for simpler code.

Packages 2.0

SAP R/3 repository is a wonderful thing. A vast warehouse of data elements, structures, tables and much more, readily available to one and all. As developers, it is extremely convenient to quickly pick these elements and pull them into our programs as necessity conveys, while our string of thought remains virtually uninterrupted.
Well, not all is sunshine and roses. If you are not careful with the mushrooms you pick you might get a poisoned one.

Ler o resto do artigo! »

Best practices
Thou shalt not use direct code in user-exits

All code to be put in user-exits (BADIs, enhancements, SMOD, etc.) should be encapsulated.

  • It’s common for an user-exit to include multiple independent parts. Each of these parts should be encapsulated in its own method. Even if it is only one line;
  • This should apply to both new implementations and changes to existing code;
  • A change to existing code should always be seen as an opportunity to organize existing code into methods, since it will have to be tested again anyway;
  • If a class associated to the respective user-exit still doesn’t exist, one should be created;
  • The name of the class should be clearly related to the name of the user-exit. Ex: for user-exit ZXF01U01 uses class Z3F_CL_ZXF01U01.

https://abapinho.com/2009/03/melhorar-os-melhoramentos/ (in portuguese)

Best practices
Thou shalt not implement in classical processing blocks

Official ABAP Programming Guidelines (page 34): [When a classical processing block is required], you should immediately delegate the execution to a suitable method (see Rule 6.37, No Implementations in Function Modules and Subroutines, and Rule 6.44, No Implementations in Dialog Modules and Event Blocks).

Best practices
Thou shalt use ABAP OO whenever possible

All new developments should be implemented using ABAP Objects unless still impossible (RFC, IN UPDATE TASK, screens, etc).
Existing developments, when rewritten, should also be converted to OO, if it proves to be realistic.
Official ABAP Programming Guidelines (page 32) rule 3.1: Use ABAP Objects whenever possible for new and further developments. Classical processing blocks may be newly created in exceptional cases only.

  • http://www.erpdb.info/wp-content/uploads/2008/09/why-abap-objects.pdf
  • http://scn.sap.com/people/thomas.jung/blog/2007/12/19/update-your-abap-development-skills-to-sap-netweaver-70
  • http://wiki.sdn.sap.com/wiki/display/ABAP/ABAP+Objects

Always use message classes in exception classes.

Exception classes let you state multiple texts describing the different possible errors that they can represent.

However, there exists an option to associate it with a message class (SE91). This allows texts to be defined as classic SE91 messages instead of being defined directly in the exception class. And it has advantages.

Ler o resto do artigo! »

Share constants among several classes

Imagine you have a herd of related classes sharing between them a whole bunch of constants. Saying the same thing a different way, would you like all the classes of the herd to have easy access to the bunch of constants?

(If you’re confused, then let me tell you that the “herd” thing was just to baffle you)

Carrying on…..

Ler o resto do artigo! »

If you still don’t use ABAP Objects you’re chicken

SAP has a book called Official ABAP Programming Guidelines which describes rules and best practices on how to program in ABAP. In there you can read:

Page 42: Rule 3.1: Use ABAP Objects whenever possible for new and further developments. Classic processing blocks may be newly created in exceptional cases only.

Page 45: Within such a [classic] processing block, however, you should immediately delegate the execution to a suitable method (see Rule 6.37, No Implementation in Function Modules and Subroutines, and Rule 6.44, No Implementation in Dialog Modules and Event Blocks).

So, if you still use Classic ABAP you’re chicken :)

Thanks dawnhops for the photo.

Greetings from Abapinho.

About Abapinho
Abapinho runs on WordPress
Articles (RSS) e Comments (RSS).