There is a lot of discussion about why we should use object oriented programming instead of plain old procedural. I have to admit it is sometimes difficult to come up with good reasons, besides the “Try it and will find out”, so I’ll blog about the reasons as I come upon them starting with: import parameters.

Last week I wanted to reuse a custom method that creates an inventory in WM, and the definition was something like this (zwm_linv_t is at table type of LINV):


Methods Create_Inventory
            importing !I_Link as LINK
                            !IT_Linv as zwm_linv_t




Why is this less then optimum design?

Side Note: Before you say, “Wait, that already uses OO ABAP”, remember that using classes doesn’t make the code object oriented. Object orientation is about design principles, not whether you use function modules or classes.

With that out of the way, why could this be improved upon?

  1. From the interface I get very little information about exactly what parameters are required since LINK has a lot of fields,
  2. I can’t use “Mandatory” keyword because it applies to the entire LINK structure;
  3. I have to look inside the code to know which fields to fill (which in this case were only 3: date, warehouse number and storage type).

A better design would be (ignoring LINV):


Methods Create_Inventory
            importing !LGNUM TYPE LGNUM
                            !LGTYP TYPE LGTYP
                            !DATE TYPE DATUM





Again you might say “There are no objects there, that’s not object oriented!”*. Well you could, but you would be missing the point. The main difference between procedural and pure OO is that in pure OO there are no structures, everything is a class. The fact that there no structures prevents you from doing stuff like the first example (and I’ve seen many people do that).

The main difference between structures and classes is that classes are responsible for their own consistency, while structures aren’t very smart. In a class, the public and therefore “mandatory” attributes are filled in the constructor which makes sure that, IF an object (instance of a class) exists, those attributes have a value. With structures that doesn’t happen, there’s nothing to ensure it.

Let’s make that clearer by replacing the method interface with one that uses an object with the attributes of LINK


Methods Create_Inventory
            importing !I_INVENTORY TYPE REF TO ZWM_INVENTORY.






When I want to create an instance of the import parameter I need to use the constructor, which will give a clear indication of the mandatory parameters (lack of polymorphism makes this trickier but…moving along). Unlike the first example I don’t need to guess, I don’t need to look into the code, I just call a method with explicit parameters, and in return I get a “bullet proof” import param.

If you ever used a BAPI and had to look in the code or debug to know exactly which fields to fill, you’ve come across the reason why structures allow very bad design, and shouldn’t be used in APIs. Saves some one time effort on the side of the programmer, by repeatedly passing it along to whoever uses the API.

*Actually in pure OO (Java, C#, Objective-C) LGNUM, LGTYP and DATUM would be classes, but let’s take it one step at a time.

To report this post you need to login first.

87 Comments

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

  1. Ulrich Rechner

    As I’m always looking for OO-approaches for classical GUI-programming, I like all kinds of ideas for good OO-designs. This is a very good example, too, and I agree with you especially regarding your example with using a BAPI you are not familiar with.

    However, there are enough cases where using structures in parameters make sense. If you want to pass data for a database operation e.g., it is not useful to transform an object to the structure or vice versa. There’s no benefit for the overhead.

    As a result, it always depends on the context if it is helpful to use “pure” OO.

    (0) 
    1. Joao Sousa Post author

      Yes, I do agree that OO approach is not appropriate for a “heavy” program, where performance is the main objective. But for all other situations, where performance is an objective but not THE objective, I tend to prefer the OO approach.

      Your example about the database operation I think it depends on the context. Is there a reason to do it? Couldn’t the parameters already be attributes of the object before the database operation is performed? But I do agree that OO isn’t always the best approach.

      (0) 
      1. Ulrich Rechner

        Indeed, it’s always interesting to discuss designs in their practical context. I think, that we have always (unfortunately) to consider the hybrid property of ABAP. E.g. internal tables are no objects, whereas in other pure OO-languages comparable datatypes are implemented as classes. That’s the burden we have to carry when programming ABAP…

        (0) 
    2. Matthew Billingham

      I regard OO-Abap as an object oriented language with many elementary data types – including structures and internal tables.

      So, I’m quite happy having complex structures as parameters to my methods. I only start passing references around when I’m programming at a higher layer in the application.

      (0) 
      1. Joao Sousa Post author

        These elementary data types have to exist because ABAP OO needs to communicate with all the “legacy” FMs but SAP recommends new developments to be made using ABAP OO.


        But it would contribute to the discussion if you could elaborate on how, in your view, that approach (using structures) is better then using classes.

        (0) 
        1. Matthew Billingham

          I just can’t see a reason (other than philosophically) why you would objectify a structure or an internal table.

          Nearly everything I’ve developed in the past six years or more has been OO. I’ve never found, while developing or maintaining that I find myself thinking”Oh, I wish I’d done that structure as a class instead”. I do not see that using complexes data structures violates SAP’s recommendation. Simply that when you develop in ABAP OO, you start at a higher level of abstraction than you do when, for example, you program in Java.

          I’ve written a few classes that have iterators, but mostly, I use LOOP AT. Again, I consider internal tables and structures are part of the language. To say – “no internal tables as parameters in ABAP OO” makes as much sense to me as “no int types as parameters in Java”.

          One thing I really like about ABAP OO, which I miss when I program in Java, is that fact that parameters are named.

          (0) 
          1. Joao Sousa Post author

            Nearly everything I’ve developed in the past six years or more has been OO. I’ve never found, while developing or maintaining that I find myself thinking”Oh, I wish I’d done that structure as a class instead”.

            Of course not, because you were the original programmer and know exactly how it behaves. The problem is when you use other people’s code, look at a structure, and have no clue about which fields are actually mandatory (my example).

            Well actually I’ve looked at my code and thought “Oh, I wish I’d done that structure as a class instead”, but that’s not the more frequent situation.


            Regarding SAP BAPIs, don’t you end up with trial and error situations? They are the most general example.

            (0) 
            1. Matthew Billingham

              Joao Sousa wrote:

              Nearly everything I’ve developed in the past six years or more has been OO. I’ve never found, while developing or maintaining that I find myself thinking”Oh, I wish I’d done that structure as a class instead”.

              Of course not, because you were the original programmer and know exactly how it behaves. The problem is when you use other people’s code…

              Not really. Once something is more than about 6 months old, it might as well have been written by another person. I can’t recall, though, ever using structures with some fields mandatory and others not. I guess it comes down to application design. Of the ones I’ve written that use structures, as far as I can recall, none of the fields are mandatory.

              While I’ve not found myself looking at design and wishing I hadn’t used a structure, I do recall deliberately using classes instead of complex structures. I.e. “oh, that needs to be a class reference, not a structure”.

              I guess it comes down to program design. I use complex data structures where it is “safe”.

              (0) 
              1. Joao Sousa Post author

                Not really. Once something is more than about 6 months old, it might as well have been written by another person

                I have to disagree on that one. It may not be fresh on your mind, but it’s not the same as someone else touching the code. From my experience some minor knowledge remains, which is enough to make a diference.

                Of the ones I’ve written that use structures, as far as I can recall, none of the fields are mandatory.

                The problem is that when I’m trying to use a FM/Method written by you, I don’t know what “rules” you used on your design.

                (0) 
                1. Matthew Billingham

                  I’ll have to disagree with your disagreement. But I’ll agree to disagree…

                  I will say that when (OO experienced) colleagues have picked up my code, they usually comment how easy it is to understand and follow. I deliberately write it that way, since my memory for technical detail is truly shocking.

                  (0) 
  2. Gregor Brett

    I like the second method the best, nice and simple 🙂

    IMO with the third you are introducing tight coupling between the two classes and risk breaking the code if ZWM_INVENTORY gets changed.

    (0) 
    1. Joao Sousa Post author

      This is simple because there are only 3 parameters, but there situations where you need to transfer a lot more information.

      That’s why I started with the second example, that was how the method ended up in SAP, but I thought it was important to give a more general example.

      you are introducing tight coupling between the two classes and risk breaking the code if ZWM_INVENTORY gets changed

      But reduces the coupling with the caller program, and makes it easier to perform unit tests. The problem with methods that have a lot of parameters is that they are almost impossible to test by themselves, unless you were the original programmer.

      (0) 
      1. Gregor Brett

        I’d create a Z structure with just the required fields if there were loads of them rather than 3 rather than wrapping it in a Z object. More code = more potential bugs (my code at least :-))

        Interested in how you think it helps Unit testing though. I guess you mean you can create ZWM_INVENTORY mock objects?

        (0) 
        1. Joao Sousa Post author

          But then the programmer that will use your method must trust that all parameters of the structure are mandatory. That was exactly the problem of the first example, in the end of the day they weren’t, and the interface didn’t provide that information.

          More code = more potential bugs (my code at least :-))

          Code is not the only source of problems, you can get impredictable behaviour (which is as, or more, time wasting as “bugs”) if the interface is not clearly defined.


          With a class if I want to set a weight I must provide a unit of measure, and the Setter will validate if the unit of measure is consistent. With structures, the caller can set whatever they want, the quantity without unit, unit without quantity, etc. The programmer can implement the validations inside the method, but for the caller, the usage becomes a matter of trial and error. “Now I get error X …. now I get error Y, etc”, instead of the rules being clear before runtime. This is what happens when you use a SAP BAPI, and we all know that trial and error is a reality.


          This blog is from the point of view of code reusage, by people other then the original programmer. The original programmer will always have first hand knowledge of what most be done, the problem is when the code is used by other people, that don’t want to read the entire method, just want to use it.


          Interested in how you think it helps Unit testing though. I guess you mean you can create ZWM_INVENTORY mock objects?

          I think it’s easier, even in SE24 it’s much easier to instanciate the import parameters and call a method or two, then having to manually fill various fields.

          (0) 
        2. Gareth Ryan

          Personally, I’d try to make it so that instead of passing structures, you are passing instances of other objects.  That way you can have one common canonical model of your objects, with their own constructor that handles the minimum data they need and then you can pass that as a parameter to the method of your other object.  So you couldn’t call the method if you hadn’t successfully created a valid instance of the source object.  As Joao mentioned earlier about the database operation, this makes more sense to me.

          Of course, it does then create other challenges, mainly around the ownership and versioning of your canonical objects but whoever said any of this would be easy?! 🙂

          (0) 
          1. Gareth Ryan

            And of course, taking my thinking a bit further, you could argue that if you want to persist an instance of that canonical object into the database, the create method should be a part of the canonical object class, not another class.  Things get complicated fast…

            (0) 
            1. Joao Sousa Post author

              Well with SAP standard objects the database operation will always be done via BAPI, which means the question of the create in the canonical object isn’t really an issue. Unfortunatly the “canonical” API is the procedural BAPI, the “CREATE” will always be “out of reach”.

              For custom developments, the objects will mostly be application specific, at least I haven’t got a problem with that yet.

              But you are right that the discussion about canonical objects is far from easy.

              (0) 
            2. Ulrich Rechner

              Talking about persistence, SAP offers the object service providing us with methods for accessing the database in order to store objects without having to code inserts/updates/selects ourselves. Thus, we have a fully OO-approach.

              However, I must admit I’ve only read about it, but I’ve never implemented it in productive projects.

              (0) 
              1. Matthew Billingham

                I’ve used persistence extensively. It’s not great for dealing with large volumes of data, or where you need SELECT… WHERE… , so you need to decide whether to break the paradigm and encapsulate some OpenSQL instead of using the persistence framework.

                For where you read and write single records, it’s great. I add another layer on top to handle Create Read Update Delete and other operations.

                (0) 
                1. Suhas Saha

                  Hi Matthew,

                  For where you read and write single records, it’s great. I add another layer on top to handle Create Read Update Delete and other operations.

                  I can vouch for that. I tried to develop an extension to the BP transaction adhering to the MVC design. And i used the persistence classes as the Model. Worked good for me 🙂

                  (0) 
  3. Naimesh Patel

    Hello Joao,

    I also have to disagree on few points here.

    Mandatory doesn’t mean that there would be a value associated to that parameter. When you have mandatory parameters, the caller can still send empty variables when instantiating the object. Those empty parameter would still create problems in the further processing.

    To avoid this situation, you need to have one more check, that all these parameters can’t be initial. You raise an exception and the caller would need to pass the actual values to move further.

    Exact same check can be also applied when you use the structures. With your comment about the BAPIs, they also have those checks on the mandatory fields. If you don’t supply those fields in the WA, you would get the exception.

    By using the structures as parameters, you can – at somewhat – overcome restriction of the overloading of the method. You can add the new fields in the structure when you inherit the method.

    I have been also using ABAP objects since last 7-8 years and I do use the structures in my objects. If you remove the structures, you can’t have Internal Tables. If you can’t have internal tables, there is no fun working with ABAP as ITAB is the most advanced objects of this Advanced Business Application Programming.

    I do agree that the classes needs to follow design principles and leverage the design patterns.

    Thanks,
    Naimesh Patel

    (0) 
    1. Joao Sousa Post author

      To avoid this situation, you need to have one more check, that all these parameters can’t be initial. You raise an exception and the caller would need to pass the actual values to move further.

      It is the responsability of the programmer to implement this exception handling, I agree, and all SAP BAPIs have these validations.

      What I was trying to point out with this blog is what you lose when you use structures as parameters, from the perspective of who is calling the method. From the perspective of the one calling a BAPI, even though the exception handling exists, I don’t particularly like the trial and error approach.

      If you can’t have internal tables, there is no fun working with ABAP as ITAB is the most advanced objects of this Advanced Business Application Programming.

      I’m not saying you should be a purist and never use ITAB. And noone is dening that they are useful and advanced, but I believe there is a price to pay. From my experience in several languages, I find OO oriented code more clean, and less prone to data inconsistencies, but of course this is subjective.

      And again I would like to point out that for programs where performance is critical, the price you pay by going procedural is worth it in my opinion.

      (0) 
      1. Matthew Billingham

        I think the point I appreciate in your blog is that structures are in some ways a poor-man’s class, and that can lead to un-safe coding. It is certainly something I hadn’t thought about before, and something I will bear in mind. (I’ve a good memory for principles…).

        (0) 
  4. Suhas Saha

    Hello Joao,

    If you ever used a BAPI and had to look in the code or debug to know exactly which fields to fill, you’ve come across the reason why structures allow very bad design, and shouldn’t be used in APIs. Saves some one time effort on the side of the programmer, by repeatedly passing it along to whoever uses the API.

    I was wondering if object references were used in BAPIs instead of structures & tables, how would an external application be able use it? Same with proxies & Webservices.

    (0) 
    1. Joao Sousa Post author

      As far as my experience goes I always create a FM wrapper when I need external communication, but in general terms intersystem communication with classes uses serialization to transmit the data across the network.

      Never used it in ABAP, don’t know if it exists.

      (0) 
      1. Suhas Saha

        So the wrapper FM would be an RFC enabled which uses tables & structures in the interface. Or how does the interface look?

        … in general terms intersystem communication with classes uses serialization to transmit the data across the network. Never used it in ABAP, don’t know if it exists.

        It exists in ABAP too, you have to use the interface IF_SERIALIZABLE_OBJECT. But i just know about it’s existence, never used it.

        (0) 
  5. Jens Petersen

    The fact remains that using classes instead of structures takes hugely more time to implement, results in a hugely larger code, and, opposite to what OO apologists keep affirming, makes it hugely harder to understand for another programmer who is not familiar with that particular program.

    (0) 
    1. Gregor Brett

      I completely agree. I am currently working through some code which is a mess of inter dependent objects. A class implements and interface, this interface implments 3 other interfaces… etc. It is a complete mess!

      There is something to be said for building “the simplest thing which would possibly work”!

      (0) 
      1. Ulrich Rechner

        Let’s agree that bad and messy code is possible both in procedural and OO-programming. I don’t know if it makes a difference to analyze an OO-chaos or a procedural chaos…

        The crucial point is that a program is structured and commented well independent from the paradigma.

        (0) 
        1. Matthew Billingham

          Except my experience is that well structured OO code takes a little longer to write, but is quicker and easier to maintain and enhance than well structured procedural code.

          (0) 
          1. Jens Petersen

            Provided you wrote that code in the first place, so you have a notion of the exact purpose and behavior of the various objects. Or you have huge documentation on every single object that in real life nobody ever cares to write.

            If you do not, objects are like variables that have a life of their own. Lacking the knowledge of their exact functionality when the code is not yours, you never really know what they “do”. Plus there is this medieval memory-based programming style that was re-introduced with ABAP OO.

            25 years back in the past, when I programmed my C64, I needed to care which data is stored where in storage, know its purpose and keep good track of it. Advances in hardware performance and programming languages allowed programmers to abstract from this, simply using variables and internal tables and let the system decide where to store them and how to manage them. In ABAP, field-symbols have been an exception, an ugly one, IMHO, and one that it is rarely really necessary to actually use (in structural programming at least). I smile at programmers who emphasize that performance is better when doing a LOOP into a field-symbol and do data changes on that rather than doing a LOOP into a variable and do a MODIFY command at the end of the LOOP. I do not deny that there is a performance difference, but after 10+ years of heavy ABAP programming, I have yet to see the ABAP program whose performance issues are based on working with internal tables and not on database accesses (or other external communication of some sort). The MODIFY variant, however, is much easier to read and understand because you explicitly see when and where table data is being changed.

            OO code now added a new level to this. Nameless data is stored somewhere in memory, and you maintain references to it. Several of these references, bearing different names and looking like variables, may well point to the same data. The programmer came up with a concept how to use this, but it is very hard to understand for anybody else who looks at the code. A hugely complex concept for something that can as well be solved in so much more… STRUCTURED… ways. 🙂

            If I look at messy structural programming code, I can start debugging key variables and structures and dig my way deeper from there until I understand how they are being used. At any point in time, looking at the field in debugger allows me to see the full content of that variable, knowing that it holds nothing beyond what I see. Compared to that, try looking at an unknown OO object in debugger! You see some data, but some fields of it will contain data references to above-discussed nameless data somewhere in memory space, and you never understand how it is all related. It may be perfectly transparent for the one who created it, but for another programmer unfamiliar with that piece of code, it is a nightmare.

            And then there are the formal changes that do not help either. When I write a FORM, I am forced to specify all the parameters both when I call it and when I implement it (unless I am doing it all with global variables, which I will neglect for now because I suppose we all agree that this would be more than messy programming style). I can be sloppy by not defining variable types in the FORM definition, or by using USING when it should have been CHANGING (as ABAP forgives changes to USING parameters), but at least they are there. So when I get a quick glance at a form from another programmer (or one that I wrote myself a year ago), I instantly have a first impression on what goes in and what goes out.

            In OO, I no longer have this convenience. I look at the implementation of a (local) method and never see its parameters, because for some academic reason these are defined elsewhere in the program, in the DEFINITION part. Yes I can double-click the method name to jump to the definition, but this still makes it harder to read whilst not serving any purpose I could see. Having the names and interfaces of all local methods that have nothing to do with each other in a list at the beginning of the program serves no use that I could see. Having the parameters of the subroutine declared at the beginning of its actual implementation does.

            Reading the code of other programmers, I even find them avoiding creating new local methods for the hassle of doing so, resulting in more subroutine-less spaghetti code. When I need a new FORM, I simply type a perform command and double-click the name I came up with. Done. I know for methods there are patterns to help me creating them, but still I need to create a DEFINITION part and an IMPLEMENTATION part, at different places of the code, potentially even in different includes, and when during writing the implementation I find that I need another parameter, or need to revamp an already existing one, I need to jump to another end of the whole program to modify the definition, which is not to be seen at the place of the implementation.

            And of course the DEFINTION needs to come before the IMPLEMENTATION in the program code. No, wait. If for some reason you do not want to do that, you can simply write DEFINTION DEFERRED. A method definition statement that tells the reader nothing about the method (except its mere existence), at a place far from any other code that has anything to do with it. Now that is helpful and makes the code easy to read! [/sarcasm]

            A former colleague of me wanted to enhance his horizon and went to the official SAP ABAP OO training course in Walldorf. When he returned, he told me that they started that course with “How to make yourself irreplaceable in your company”, followed by a demonstration on how to quickly create an OO code that no other programmer will have a chance of comprehending. After the course, his final conclusion was that ABAP OO was a sorry effort of introducing something new.

            (0) 
            1. Matthew Billingham

              I can’t agree with much of your valuation. Well, your complaints are valid, but you’ve got the wrong target – what you’ve encountered is badly written OO. Perhaps if you’d encountered well written OO, you’d have a different view. However, even well written ABAP-OO is hard to understand for the inexperienced. That’s why I learned to program in OO in Java. Much easier, and then you can apply what you’ve learned to the ABAP environment. Which is what I did ten years ago.

              I’ve spent a lot of time debugging SAP OO code to find out how it works, and didn’t find it difficult at all. Mainly in the Web Dynpro and BW run-time. Some in PI. Also, I’ve developed on an HR system where an entire framework has been built – by other programmers – and find it a joy to use. Without having to refer to documentation.

              Also, what I’ve developed over the years is supported by off-shore programmers. They do not find it difficult to support what I’ve written, and enhance it where necessary. Furthermore, when I come back to what I wrote six, seven or even eight years ago – I don’t have difficulty.

              Your complaint about the parameters for local classes has some validity. But I’ve not encountered (in fairly wide experience of many clients) much that uses local classes extensively – the core of the WD run time is an exception, but it’s not that hard to figure out. Compare however subroutine parameters with global class parameters, and OO wins without question – named parameters, with enforced typing.

              (0) 
              1. Jens Petersen

                Your complaint about the parameters for local classes has some validity. But I’ve not encountered (in fairly wide experience of many clients) much that uses local classes extensively

                How do you do it then? Use FORMS after all? Define global methods in SE24 for every small subroutine you need? Or avoid subroutines and write spaghetti code instead?

                (0) 
                1. Joao Sousa Post author

                  Define global methods in SE24 for every small subroutine you need?

                  Why not? And by the way that’s how you do it in languages like Java or C#.

                  (0) 
                2. Matthew Billingham

                  There’s no such thing as a global method. Do you mean global class? If so the answer is “yes, of course I do”. Not one class per method, but I group the methods together according to their object context.

                  That’s why it’s call “object oriented”

                  (0) 
                  1. Jens Petersen

                    And that’s why “object oriented” appears to be such a horrible monster to me!!!

                    What you say hugely increases the hassle of setting up a new method! I am heavily structuring my programs with FORMs. Whenever I need a new one, I just type the PERFORM command at the place where I want it, then double-click on the FORM name I just came up with, and voilà: I am sitting in the auto-created implementation part and can begin typing.

                    However, I remember fixing bugs in a program of someone else. It was OO code, albeit bad one by all means, as it was effectively procedural code written with OO elements. Nonetheless I did my best to keep to its style (because no code is more horrible to read than one that jumps between coding philosophies from line to line). The programmer used methods, but effectively used them as FORMs. I noticed she was not using very many methods though, and adding to the code I found myself also avoiding to add new methods, because the declaration of a new (local) method is a so much greater hassle than the declaration of a new FORM.

                    Now I do not even dare to imagine what would happen if I needed to define each of those globally in SE24!!! I would end up writing spaghetti code, avoiding to create new methods wherever possible, because I am just not prepared to start a different transaction and define a big interface there for every small subroutine that I want to code. Such a thing is deadly to the discipline of any programmer! Dividing the code into clean, manageable blocks of code should be a fluent process that does not take much of the programmer’s time to do (and I am not talking about the time a programmer needs to consider a good structure, I am talking about sheer interface time it takes him to go through all the steps that are required to enter it into the machine).

                    I mean, even in procedural programming, you do not create a new FM in SE37 every time you need a small subroutine! Doing so would both be silly and create a lot of unnecessary work that would do nothing to make the code better readable (rather the contrary). FM’s in SE37 (and IMHO public methods in SE24) are there for subroutines that are supposed to be used cross-program.

                    (0) 
                    1. Joao Sousa Post author

                      Now I do not even dare to imagine what would happen if I needed to define each of those globally in SE24!!! I would end up writing spaghetti code, avoiding to create new methods wherever possible, because I am just not prepared to start a different transaction and define a big interface there for every small subroutine that I want to code. Such a thing is deadly to the discipline of any programmer!

                      As Uwe has shown below that isn’t really a problem in more recent Netweaver releases.

                      And let me say that FORMs are so easy so easy, that many times I’ve seen programs that end up only with Z<program>_F01, with 100 routines in a single include, which is fabulous for change management…

                      (0) 
            2. Joao Sousa Post author

              If you do not, objects are like variables that have a life of their own. Lacking the knowledge of their exact functionality when the code is not yours, you never really know what they “do”.

              Well, the point is the precisely that you don’t need to know. If I’m using Cocoa or the Android API I don’t care how it works, it’s an abstraction layer. If you need to know how the class works in order to use it, it’s a case of bad OO design (which I’ve seen many times when people shift from procedural to OO in ABAP).

              Like Matthew said, it helps to learn OO in Java or C# and them come back to ABAP with that knowledge. People shifting from procedural to OO in ABAP tend to use classes in the same way as in procedural, and don’t understand the purpose of having private variables.

              That doesn’t mean Java people are perfect. Actually while I’ve never felt the need to look into the way Android SDK is implemented, I’ve had to look into a library like Ksoap because the documentation was lacking and the interface not very well designed.


              The MODIFY variant, however, is much easier to read and understand because you explicitly see when and where table data is being changed.

              That’s debatable. If I’m changing the structure inside the loop, it means I really wish to change it, having a explicit MODIFY is a potencial point of failure (wrong index, forget to make the modify, etc).

              At any point in time, looking at the field in debugger allows me to see the full content of that variable, knowing that it holds nothing beyond what I see.

              I start by arguing, that it’s a matter of usage. If you are used to OO, you will of course understand it better. And you are forgetting the problems with procedural that arise from the lack of encapsulation. I’ve seen more then my share of situations, many in standard SAP code, where global variables are filled and I have no clue where or how. You say you will “never understand how it’s all related” but that’s the same with structures. If you have hundreds of structures will you know how it is all related?

              In OO, I no longer have this convenience.

              And that’s a good thing. Are you advocating that allowing sloppy programming is good? I didn’t get this one.

              I know for methods there are patterns to help me creating them, but still I need to create a DEFINITION part and an IMPLEMENTATION part, at different places of the code, potentially even in different includes, and when during writing the implementation I find that I need another parameter, or need to revamp an already existing one, I need to jump to another end of the whole program to modify the definition, which is not to be seen at the place of the implementation.

              ABAP for Eclipse clearly helps with this one. Makes it really easy to jump from declaration to implementation and vice-versa.

              he told me that they started that course with “How to make yourself irreplaceable in your company”, followed by a demonstration on how to quickly create an OO code that no other programmer will have a chance of comprehending.

              Blame the trainer, not OO ABAP.

              (0) 
              1. Jens Petersen

                Well, the point is the precisely that you don’t need to know. If I’m using Cocoa or the Android API I don’t care how it works, it’s an abstraction layer. If you need to know how the class works in order to use it, it’s a case of bad OO design (which I’ve seen many times when people shift from procedural to OO in ABAP).

                Thank you for pointing this out, because this is exactly what I consider the ideology of OO supporters that does not hold against reality. The affirmation that you do not need to know how the code (or an object) works only holds true under two important preconditions:

                • The code works properly, so there is no need for you to fix it.
                • You have understood the purpose and intended functionality of an object.

                Now when you encounter a program that does not do what it should, it is well possible that the coding of one of is objects is faulty. And that is the point when you wished you would understand what it does and how it works!

                I am well familiar with the concept of encapsulation. This concept is nothing new in OO; every simple FORM or FM is an example of procedural encapsulation. But encapsulation is only good as long as the encapsulated routines can be understood and debugged. OO with its high abstraction layers deploys serious obstacles here.

                The second bullet is even more important: Even when an object works as it should, that is of little use for you when you have no idea of its purpose or exact functionality. And that is the big problem a programmer has when encountering the OO code of another programmer. You find that the program is not working properly, you find that it is working with an object, you find that you do not know what said object does. You see methods of it called and have no clue – other than their name which may or may not help – what they are supposed to do. You have no clue what said object is supposed to contain. Debugging will lead you right into the object, overstepping the boundaries of encapsulation as if it were not there. Tell me, how do you debug an object whose purpose you do not know?

                In structural programming, the worst thing you can encounter is a variable, structure, or internal table whose purpose you do not know. By looking into it in debugger and possibly putting a watchpoint on it you will usually find out quickly enough. The purpose of unknown forms – if not obvious – can usually be found out by seeing what it does to variables.

                That’s debatable. If I’m changing the structure inside the loop, it means I really wish to change it, having a explicit MODIFY is a potencial point of failure (wrong index, forget to make the modify, etc).

                Wait a minute… if you use a MODIFY command, it does not mean or point out that you really wish to change it?

                The contrary is true… a MODIFY command clearly states that the internal table is to be changed. Altering a field symbol is much more prone to lead to table changes that were not intended by the programmer in the first place. As a matter of fact they are much less evident to another programmer reading and trying to understand the code.

                Of course it is possible to make mistakes with the MODIFY command, like with any other command. Forgetting the MODIFY command is one.

                Wrong indexes are hardly an issue. In a LOOP, you do not need to specify the index in the first place, and the fact that you need to explicitly specify one outside LOOPs forces you to stop and think about it and make sure you are specifying the right one, where just altering a field symbol holds a far higher likelihood of accidentally hitting one that points towards a wrong table line. For a second programmer, there is hardly something easier to understand than an explicitly denoted table index at the place where the change takes place.

                I’ve seen more then my share of situations, many in standard SAP code, where global variables are filled and I have no clue where or how.

                I fully agree that extensively working with global variables is messy and should be avoided. The times when such a thing was necessary in procedural programming are long over though. They were already over in release 3.x.

                That being said, I have a far easier time debugging global variables with the help of watchpoints than debugging data references to unknown objects.

                (0) 
                1. Joao Sousa Post author

                  Thank you for pointing this out, because this is exactly what I consider the ideology of OO supporters that does not hold against reality.

                  I said that in context. If the code is faulty, then you need to understand it, like any other piece of code. A function module isn’t crystal clear either, if it doesn’t work you really need to “dig in”, and I don’t see how a Class is more obscure then a FM.

                  The second bullet is even more important: Even when an object works as it should, that is of little use for you when you have no idea of its purpose or exact functionality. And that is the big problem a programmer has when encountering the OO code of another programmer.

                  I don’t see how that is any different from procedural. If there is not documentation, a FM will be as hard to understand as any class or method. The fact is that with ABAP Docs and intelisense (in ABAP For Eclipse) OO ABAP is reaching the maturity of other solutions like Java. Maybe people are just used to bad documentation, but they will see the beauty of Java Docs and the equivalent ABAP Docs (which unfortunately can’t be exported to HTML but it’s coming).

                  In structural programming, the worst thing you can encounter is a variable, structure, or internal table whose purpose you do not know.

                  Stop right there, now you are going for “Apples and Oranges”. If you want to say OO programming is complex, you need to add FORMs and FM to that comparison. Like I said before a non-documented form or FM is as abstract as a non documented class.

                  Wait a minute… if you use a MODIFY command, it does not mean or point out that you really wish to change it?

                  It does, but changing the structure inside the loop also means I want to change it. And then I don’t have the “option” of forgetting the MODIFY command.

                  The contrary is true… a MODIFY command clearly states that the internal table is to be changed. Altering a field symbol is much more prone to lead to table changes that were not intended by the programmer in the first place. As a matter of fact they are much less evident to another programmer reading and trying to understand the code.

                  I’m changing the structure but I don’t want to change the table? I think it’s much more confusing, but well, it’s subjective.

                  fully agree that extensively working with global variables is messy and should be avoided. The times when such a thing was necessary in procedural programming are long over though. They were already over in release 3.x.

                  You still need to use them if you make a SE51 transaction, which many classic ABAPers do since they don’t know Webdynpro.

                  (0) 
                  1. Jens Petersen

                    The discussion appears to literally be going slit here 😆 , but anyway.

                    I said that in context. If the code is faulty, then you need to understand it, like any other piece of code. A function module isn’t crystal clear either, if it doesn’t work you really need to “dig in”, and I don’t see how a Class is more obscure then a FM.

                    A FM has a clear set of variables (as a generic term for all sorts of fields and tables) that go in and others that come out. You send some values in and get others out as the consequence. Basically, that is all, and that is how most FM’s work.

                    I agree that FM’s partially violate this concept by having their own local variables which they store across calls and share within their function group, so calling the same FM twice will not necessarily yield the same effect in both cases. I strongly dislike this aspect of FM’s as it IMHO violates the idea behind the FM concept and can make an FM hard to understand (especially when the author failed to equip it with a proper documentation).

                    The funny thing is that this aspect I dislike most about FM’s is their greatest parallel to OO concepts. Basically you can say that a function group is something similar to an object, with the FM’s being its methods. Fortunately, most of the time the FM’s are independent and provide a well-defined functionality that only depends on the parameters you are providing at run-time.

                    But the thing is that even if the code is not faulty, you still need to understand it if you plan on working with it. For example, if you want to exhance a program, add new features to it, and this program uses objects, then you will have to analyze and understand every single of these objects to be able to properly address and use them on your own. Assuming that they are not thoroughly documented (and I have yet to see an OO program that has all its objects and their methods extensively documented), you will still need to dive into the implementation of every single object and analyze it, understanding obscure data references to other objects and the like. Needing to use only one object in your own code can force you to analyze 10 other objects to which the object in question references, just to properly understand how the object in question works so you can correctly address it. It is a nightmare.

                    I don’t see how that is any different from procedural. If there is not documentation, a FM will be as hard to understand as any class or method.

                    No. A FM works with parameters and variables, which are way easier to track and whose purpose is much easier to understand than objects that refer to nameless data somewhere in the memory universe. Variables contain values of known data type, and is something you can always start with. They do not have a life and unknown functionality of their own. They are created once and then defined by their name, not created in multiple nameless instances that auto-vanish by means of an ominous garbage collector when no reference to them happens to exist anymore.

                    When you read a variable name, it is that variable. When you read an object reference name, it could be any of several instances of that object. The logics behind this is created by the programmer, but hardly ever documented, so you will have to find out on your own.

                    Like I said before a non-documented form or FM is as abstract as a non documented class.

                    And I decisively contradict here, because the elements a form or FM works with are far less complicated than that of an object. Worst thing you can encounter are nested tables in a structure.

                    It does, but changing the structure inside the loop also means I want to change it.

                    It does change it, albeit less apparent to the reader.

                    And then I don’t have the “option” of forgetting the MODIFY command.

                    With the same logics I could say that FORMS > objects because when I use a FORM, I cannot forget the constructor. 🙂

                    In other words: Whatever approach you use, it is up to you to use it properly, and you can make mistakes in any approach. Missing MODIFYs will usually become quickly evident once the programmer test-runs his piece of code.

                    Altering a field symbol is much more prone to lead to table changes that were not intended by the programmer in the first place. As a matter of fact they are much less evident to another programmer reading and trying to understand the code.

                    I’m changing the structure but I don’t want to change the table?

                    You are changing the value the field symbol references to, which could be anywhere. This table, another table, a single variable of type LINE OF TABLE, even the nirvana if the field symbol is not properly assigned yet. When assigning a value to a field symbol, it is far less apparent to the reader what you are doing than when assigning a value to a work area (preferably a header line, IMHO) and then doing an obvious MODIFY TABLE command, especially with explicitly stated index (or in a LOOP). And since it is less apparent what is happening, there is a greater danger of programmer mistake here.

                    You still need to use them if you make a SE51 transaction, which many classic ABAPers do since they don’t know Webdynpro.

                    I grant you that one, but you are always free to consider these variables as GUI interface variables into which you copy your output. Even if you are not that disciplined, simple Dynpro output fields usually do not create a complexity that would make the whole program hard to understand, seeing that these variables cannot even contain structures, let alone nested variables or tables, not to mention data references. You only get that level of complexity when you start using advanced containers, which are OO and way harder to use than simple output fields and standard ALVs (especially SLIS-based ones).

                    (0) 
                    1. Joao Sousa Post author

                      The funny thing is that this aspect I dislike most about FM’s is their greatest parallel to OO concepts. Basically you can say that a function group is something similar to an object, with the FM’s being its methods. Fortunately, most of the time the FM’s are independent and provide a well-defined functionality that only depends on the parameters you are providing at run-time.

                      I think this deserves a blog in itself. It was on my mind to write it, now I will. 🙂

                      (0) 
    2. Joao Sousa Post author

      The fact remains that using classes instead of structures takes hugely more time to implement

      If you are not used to it, certainly. Besides “speed” is not always the thing you are looking for because it “gets you” farther along the path.

      I don’t want fast programmers, I want robust programmers. One of the points I make in the blog is that OO is more robust, not that it is faster. If you don’t take the time to validate the input or the consistency of the structure, sure it will be faster

      results in a hugely larger code

      Why? In fact, I find it quite the opposite, especially if you use the new notation on 7.4.

      makes it hugely harder to understand for another programmer who is not familiar with that particular program.

      I think that depends on the programmer. I’ve some structure based programs that were almost impossible to comprehend.

      (0) 
      1. Jens Petersen

        The fact remains that using classes instead of structures takes hugely more time to implement

        If you are not used to it, certainly. Besides “speed” is not always the thing you are looking for because it “gets you” farther along the path.

        Being used to it or not has nothing to do with the sheer length of the code. I own the book “ABAP Objects” from SAP press. There are program examples in there, one structural, then the same in OO. Where the structural code is 1 page long, the OO code covers 2 pages. The sheer length of the code already makes sure it takes a lot longer to complete (especially seeing that writing the longer code does not make its content easier. You just have +100% lines that you need to make sure are syntactically and semantically correct.)

        Sometimes you hear the argument that code being longer may well be worth it when in return it is easier to understand. In theory, this is true. In reality, however, I found that in almost all instances in which I found a way to write a shorter code that performs the same functionality, said shorter code was also easier to read and better to understand. A good example is the LOOP-EXIT-ENDLOOP-structure that some (IMHO inept) programmers use instead of the READ TABLE command.

        I am sure examples can be found where a shorter code is harder to understand. But as far as my experience goes, these are exceptions to the rule. By the way, this explicitly goes for header lines which have been forbidden in OO, making the same code a lot more of a mess. Programmers are expected to be able to keep track of where various data references point towards in open memory space, but are apparently supposed not to be able to derive from context at first glance whether a table name is referred to as the internal table or its header line. This is pretty ridiculous, and the code already looks a lot more messy and harder to read simply due to the countless work area variables that need to be introduced as the consequence.

        It is for a reason that in OO, programmers are practically forced to use 2-character-type abbreviations at the beginning of all of their variables  because otherwise they would quickly get lost which variable has which type and purpose. In procedural programming, this can also be done, but there is no real need, because procedural programs are easy enough to read and comprehend without such measures.

        I don’t want fast programmers, I want robust programmers.

        Meanwhile, I care little for robust programmers, but desire robust programs. Part of a program being “robust” is another programmer, unfamiliar with the code, having the chance to understand it in detail so that long-term program maintenance can be guarateed. Look at standard SAP code for instance. I am sure you have faced problems before in which you resorted to debugging the standard code to see what it does. Doing this on standard SAP code is rarely an easy thing, but often enough it leads to a solution. However, if the SAP standard code in question is OO code, you so quickly get lost that you can rarely dream about understanding what it is doing.

        One of the points I make in the blog is that OO is more robust, not that it is faster. If you don’t take the time to validate the input or the consistency of the structure, sure it will be faster

        IMHO it is a misconception that OO would be more robust. OO forces you to heed more formalities. There might be a certain value in this as most programmers are lazy and do not do this on their own. However, if you program procedural code with discipline, using meaningful variable names (using all of the 30-character-name-length-limit if need be) and write two sentences of functionality explanation at the beginning of every single FORM you create, you will get a code so well-understandable and readable that no OO code could ever match it.

        And you will still end up typing a two-digit-percentage less characters in the process.

        results in a hugely larger code

        Why? In fact, I find it quite the opposite, especially if you use the new notation on 7.4.

        Because everything in OO is longer. Methods require so much formal stuff, work areas clutter up your code with useless declarations, objects need to be declared and equipped with attributes. As I said before, in the official SAP Press “ABAP Objects” book sample codes in procedural and OO style reveal the OO variant to be two times the length at same functionality.

        That being said, I do not have 7.4 yet and am not familiar with the new notation.

        makes it hugely harder to understand for another programmer who is not familiar with that particular program.

        I think that depends on the programmer. I’ve some structure based programs that were almost impossible to comprehend.

        I agree that you can do very badly in procedural programming. But you can do even worse in OO. Trust me on that one. And the same programmer will.

        The reason is that the dependencies in structural programming are way less complex than those in OO programming, so the impact is smaller and it is easier to “decompile” messy code.

        (0) 
        1. Suhas Saha

          another programmer, unfamiliar with the code, having the chance to understand it in detail

          When you say OO-programs are difficult to comprehend by subsequent developers, you must specify “who are not so comfortable in OOP”.

          From my experience, i can tell you that when i have seen coding in the WDA, BOPF framework i can easily understand what’s going on. I can identify if the framework is using some design pattern (singleton, MVC, facade et al.).

          But if the developer doesn’t have a working knowledge about it, he will b**ch about the complexity. Some of the complaints i have heard are –

          • Why the hell is the class instantiation level not defined as PUBLIC?
          • Why is the class reference instantiated in the static constructor?
          • Who needs a static constructor?

          I think in the end it’s a matter of perception. If the developer is not comfortable with OO programming he’ll complain about the complexity, length of the code etc. OOP enforces stricter programming guidelines than procedural programming. But it’s upto the developer to adhere to these guidelines or shun them.

          (0) 
          1. Jens Petersen

            OOP enforces stricter programming guidelines than procedural programming. But it’s upto the developer to adhere to these guidelines or shun them.

            Do you realize the contradiction between your last two sentences? If OOP “enforced” stricter programming guidelines, it would not be possible to shun them. Since you can, it is neither fish nor fowl.

            (0) 
            1. Joao Sousa Post author

              I think you are confusing guidelines with compiler checks. The compiler can’t force you to design a program in a OO way, it can only enforce the syntax.

              (0) 
        2. Joao Sousa Post author

          Being used to it or not has nothing to do with the sheer length of the code. I own the book “ABAP Objects” from SAP press. There are program examples in there, one structural, then the same in OO. Where the structural code is 1 page long, the OO code covers 2 pages.

          I believe I’m starting to see a pattern. I’ve never read that book (I learned OO in Objective-C and Java), but by the way people talk about I don’t think it is very good (sorry author, that’s my view). The examples are just poor. And it’s consistent with the way you described training being handed out in Waldorf.

          Just recently I picked up a procedural program (that used classes…), and reconstructed it from zero. I can honestly say I used about one tenth of the code, and in the end I asked the original programmer what he thought. He agreed that with that example, he could see the benefits of OO programming.

          In OO (7.4) you can do things like:

          try.

               data(lo_delivery) = new ZSD_DELIVERY( lv_vbeln ).

               lv_xblnr = lo_delivery->get_sales_order( )->reference.

          catch zcx_more_then_one.

               “Do something

          endtry.

          Does this generate more code then procedural? Not really.

          It is for a reason that in OO, programmers are practically forced to use 2-character-type abbreviations at the beginning of all of their variables  because otherwise they would quickly get lost which variable has which type and purpose.

          ? The purpose, the same as with structures or variables, is defined by its name.

          If you define lo_x, or ls_x, you will still have no clue what the variable is about.

          Doing this on standard SAP code is rarely an easy thing, but often enough it leads to a solution. However, if the SAP standard code in question is OO code, you so quickly get lost that you can rarely dream about understanding what it is doing.

          Why? In fact, I would argue that standard SAP code is very bad because it doesn’t respect any of the OO rules, especially encapsulation. The UI code is mixed with business logic, global variables all over the place, SAP code is a terrible example.

          However, if you program procedural code with discipline, using meaningful variable names (using all of the 30-character-name-length-limit if need be) and write two sentences of functionality explanation at the beginning of every single FORM you create, you will get a code so well-understandable and readable that no OO code could ever match it.

          If. If you program procedural with discipline, which people usually don’t do because they are lazy. All of us are a bit lazy, that’s why having rules is important.

          You can have rules for procedural as well, but the advantage is that OO rules are global (and specially cross language). When I enforce rules in my projects, I’m not enforcing my rules, I’m enforcing the rules that are written in so many books that it’s hard for programmer to dismiss them. You can set rules “because you say so”, but I find global rules much more easy to follow.

          For example, making sure you only have database operations for a given object, inside that object, immediately makes it impossible for people do to a SELECT or UPDATE in a Webdynpro View. Lazy code will be sent back, with little justification given.

          I agree that you can do very badly in procedural programming. But you can do even worse in OO. Trust me on that one. And the same programmer will.

          That last part is specially true, but you know why? Because that same programmer will probably be using classes in the same way he is used to using procedural, or trying to use only half the OO guidelines. I’ve seen that behavior before, and yes, it leads to indescribable bad code. But that’s not a problem in OO ABAP it’s more related to the way people are introduced to OO ABAP.

          Do you know I started learning Objective-C, even before Java? Learning about abstract OO concepts, even before I touched a line of code. And that’s what’s really important, if people don’t follow the guidelines, it’s a huge mess.

          (0) 
          1. Suhas Saha

            I’ve never read that book (I learned OO in Objective-C and Java), but by the way people talk about I don’t think it is very good (sorry author, that’s my view).

            I had read that book & used it to start writing OO-ABAP. But as i started using OOP extensively & i had questions which the book did not answer (i think because they were beyond the scope of the book) i grabbed a copy of “Head First Design Patterns” and used it as a reference.

            May be my approach was wrong learning OO in ABAP and not in Java, C#. I did not learn them in college, and i did not have enough time to start learning a new language at that point of time 🙁

            (0) 
          2. Jens Petersen

            In OO (7.4) you can do things like:

            try.

                 data(lo_delivery) = new ZSD_DELIVERY( lv_vbeln ).

                 lv_xblnr = lo_delivery->get_sales_order( )->reference.

            catch zcx_more_then_one.

                 “Do something

            endtry.

            Does this generate more code then procedural? Not really.

            As I mentioned before, I am not familiar with 7.4 notation yet as we do not yet have 7.4. Chances are 7.4 does offer some improvements (even though I reckon the basics remains the same). For that reason my ability to parse your lines is limited (although I have an idea what they do).


            ? The purpose, the same as with structures or variables, is defined by its name.

            If you define lo_x, or ls_x, you will still have no clue what the variable is about.

            I agree that the name is important. That was not my point.

            In structural programming, you need neither lo_ nor ls_ nor lv_ nor wa_ nor ty_ nor tt_ nor whatever else, because from the context the type of the variable is usually evident. These prefixes already demonstrate that OO introduced a level of complexity that an only be handled by adding variable type information to the name of he variable just to keep it all manageable.

            If. If you program procedural with discipline, which people usually don’t do because they are lazy. All of us are a bit lazy, that’s why having rules is important.

            I grant you that one. I do have this discipline in my programs, however, and I claim the resulting code is easier to understand than anything that could be done with OO to achieve the same result while still being faster to code and shorter to read.

            So this is really about enforcing discipline in programming, not about revamping the whole programming language and replacing it with something hugely more complicated.

            You can have rules for procedural as well, but the advantage is that OO rules are global (and specially cross language).

            Are they? You just pointed out yourself that not even SAP themselves care for these rules. So OO rules are easy to ignore, and they are being widely ignored in reality. OO fails to live up to its claim to enforce more disciplined programming, even though it does enforce some additional syntax. In the end, it is the programmer that needs to discipline himself. But once we agree on that, there is no longer any need to replace structural programming, as the code is so great, short, and easy to understand when well written and properly documented (again, with “properly documented” I mean like 2 sentences per FORM in the FORM header, nothing like you would need to properly document an OO object, its functionality, and the purpose of all its methods and attributes so that a programmer who is unfamiliar with the project has a chance to understand the code.

            For example, making sure you only have database operations for a given object, inside that object, immediately makes it impossible for people do to a SELECT or UPDATE in a Webdynpro View.

            Which is IMHO pretty horrible because it makes it impossible to quickly write a report that displays some data. Doing so requires the author of the report first to dive into the object and understand all details of it so he can choose the right method and properly supply its parameters. If the data he needs is not yet supplied by any method – oops.

            Not to mention what this means for the ability to create queries.

            (0) 
            1. Joao Sousa Post author

              As I mentioned before, I am not familiar with 7.4 notation yet as we do not yet have 7.4. Chances are 7.4 does offer some improvements (even though I reckon the basics remains the same).

              What is new in 7.4 is:

              • data(lo_delivery): Inline declaration of a variable with implicit type similar to the VAR in C#.
              • new ZSD_DELIVERY( lv_vbeln ): The NEW keyword with replaces/complements CREATE OBJECT. The NEW keyword is used in most object oriented languages.


              The rest is the same in 7.31.

              In structural programming, you need neither lo_ nor ls_ nor lv_ nor wa_ nor ty_ nor tt_ nor whatever else, because from the context the type of the variable is usually evident.

              How? I don’t think it is that evident, but even considering it is, I don’t see why it is more evident then OO objects. The fact that with objects you use -> and => all the time makes it pretty clear that it is a object.

              Are they? You just pointed out yourself that not even SAP themselves care for these rules. So OO rules are easy to ignore, and they are being widely ignored in reality.

              Since I was talking about legacy procedural code, I think you misinterpreted my words.

              OO fails to live up to its claim to enforce more disciplined programming, even though it does enforce some additional syntax. In the end, it is the programmer that needs to discipline himself.

              I don’t think you understood my argumentation. I wasn’t saying that code review wasn’t necessary, it is. Compiler will never check design guidelines. I was saying is that guidelines for OO are more global and cross language, while procedural has basically no written rules.

              The fact that it has no written rules, means that they are very specific for each project and each project leader, which may lead programmers to question their validity. OO guidelines are more global, and widely documented (mainly because they are not specific to ABAP).

              I mean like 2 sentences per FORM in the FORM header, nothing like you would need to properly document an OO object, its functionality, and the purpose of all its methods and attributes so that a programmer who is unfamiliar with the project has a chance to understand the code.

              I really don’t understand why a FORM is implicitly easier to understand then a class method, and that’s the main reason why we won’t agree on this topic. You have failed to explain why a form can be explained in 2 sentences while a method needs extensive documentation.

              If you want to talk about Classes, then you need to compare their complexity to Function Groups, not FORMs.

              Which is IMHO pretty horrible because it makes it impossible to quickly write a report that displays some data. Doing so requires the author of the report first to dive into the object and understand all details of it so he can choose the right method and properly supply its parameters. If the data he needs is not yet supplied by any method – oops.

              You are going into Apple & Oranges territory yet again. If you are describing a situation where the author of the report needs to use existing data sources like a class, the equivalent procedural scenario would be to use an existing FM (or FORMs in another include) as a datasource

              In that scenario he would need to understand the FM/FORM, and maybe the FM/FORM doesn’t provide exactly what he wants, so – oops. It’s exactly the same.

              Or maybe you are falling into the other pitfall of OO for ABAPers which is the canonical class. In that case I think you should read Package in object name, why should you do it? . In that blog I argue that there shouldn’t be such a thing as a canonical class (for example for deliveries), that they should be package specific.

              EDIT: And by the way I’m not dogmatic about it. If all you want is a simple ALV report with few lines of codes go ahead and do the select outside the class. I enforce these rules for medium/large developments.

              (0) 
              1. Jens Petersen

                In structural programming, you need neither lo_ nor ls_ nor lv_ nor wa_ nor ty_ nor tt_ nor whatever else, because from the context the type of the variable is usually evident.

                How? I don’t think it is that evident

                Because you simply do not have that heap of esoterical types, like REF TO DATA, and you also have less garbage variables, like WA_WORKAREA ones. I have never had the faintest difficulty telling a header line from its table based on context. The introduction of forced work areas clutters up the code big time and makes it a whole lot harder to read. It is as if SAP doubted the ability of programmers to abstract. At the same time, however, they are introducing far more abstract and theoretical concepts like data references and nested objects which require far greater ability to think in abstract terms than a simple header line ever can.

                Just to give you an example: When in one of my programs you read a field with the name “MATNR”, then you have my fullest faith that you will instinctively (and correctly) assume that this is a simple field which holds a material number and is of type MATNR (LIKE MARA-MATNR).

                Disallowing the LIKE command and in return making the TYPE command ambiguous so that depending on context, TYPE now sometimes refers to a real type and sometimes refers to a structure where you normally would have used LIKE, did nothing to make ABAP code better readable either.

                but even considering it is, I don’t see why it is more evident then OO objects. The fact that with objects you use -> and => all the time makes it pretty clear that it is a object.

                That much is true. As far as object references are concerned, they are apparent by syntax. That does not justify the above changes though, which were introduced with and enforced by OO programming in ABAP.

                I was saying is that guidelines for OO are more global and cross language, while procedural has basically no written rules.

                I contest that statement. There are rules for good procedural programming. They even emphasize the value of encapsulation, which is nowhere near being a new feature of OO. You should avoid global variables, you should structure your piece of code into lots of procedure blocks with human-understandable names, you should document these FORMs well (unless they are so small and simple that a mere glance at them reveals their purpose) and you should take good care of their interfaces, specifying their type wherever possible and not messing up USING and CHANGING (even though ABAP does not really distinguish between these and will allow you to modify any USING parameter as you like).

                I really don’t understand why a FORM is implicitly easier to understand then a class method

                Because unless global variables are abused, the output of a FORM is 100% dependent on its input, so at any debugging point in your program, you can always 100% predict what the FORM that is about to be called will do and return. Meanwhile, the behavior of a method largely depends on the hidden (private) attributes that have been fed into that object up front, so upon calling said method in debugger, you lack important information about what behavior to expect. You could say that private attributes of objects are similar to global variables in procedural code in that they influence the course of your subroutines although not being part of the interface and therefore not apparent to the caller of the subroutine. Such a thing is called messy and shunned in procedural programming but encouraged in OO.

                You are going into Apple & Oranges territory yet again. If you are describing a situation where the author of the report needs to use existing data sources like a class, the equivalent procedural scenario would be to use an existing FM (or FORMs in another include) as a datasource

                The include is meaningless; a double-click on the FORM name will take me there in an instant no matter what. Once there, I will see the complete interface definition instantly at a glance, rather than having to hop to a “DEFINITION” part, and, in case of SE24, having the various parts of the interface scattered across multiple tabs.

                Here again you see another drawback of the OO concept in ABAP: The whole programming interface around it is so scattered across many screens and tabs you have to switch through, where in structural programming, especially with FORMs, you have all the information you need well-readable at one place.

                And to follow your analogy further, the FORM (in another include if you like) will still be 100% defined by its interface, save for any globals or memory exports which should be scarcely used, while the method has valuable information hidden inside so you do not know what it will do.

                In that scenario he would need to understand the FM/FORM

                But besides way easier to create and read, the FORM is defined by its interface input and output only, which makes it hugely easier to understand and debug compared to a method, where you never know whether the output differs from your expectation due to an error or just because a private attribute hidden inside is not what it should have been.

                (0) 
                1. Joao Sousa Post author

                  Here again you see another drawback of the OO concept in ABAP: The whole programming interface around it is so scattered across many screens and tabs you have to switch through, where in structural programming, especially with FORMs, you have all the information you need well-readable at one place.

                  There is a source-code based editor version of SE24, where you edit the code just like SE38. And besides the new editor going forward is ABAP for Eclipse where you only have the source-code based editor.

                  The rest I won’t comment, since it’s pointless to continue. I think we both made all the arguments.

                  (0) 
                2. Matthew Billingham

                  Sorry Jens, I think you’re stuck in the 1980s. The fact that you still think tables with header lines are a good idea proves that. Programming paradigms and actual best practice have moved on considerably since then.

                  (0) 
        3. Matthew Billingham

          this explicitly goes for header lines which have been forbidden in OO, making the same code a lot more of a mess

          😯 Arguing that tables with header lines are better than separately defined work areas… you’re kidding right? What next – “it’s better to define variables as global, then you don’t need to deal with all these messy form parameters”. Methinks the poster protesteth too much…

          programmers are practically forced to use 2-character-type abbreviations

          Did you miss the recent discussions about prefixes for variables? I’m currently developing an application in which I have an internal table of reference to objects representing questions. I’ve called it questions. I read it into a variable called question. What could be simpler?

          Part of a program being “robust” is another programmer, unfamiliar with the code, having the chance to understand it in detail so that long-term program maintenance can be guaranteed.

          This is not an argument against OO, since there is an implicit understanding that the programmer is familiar with the language. Otherwise your definition of “robust” would mean that a PL1 program is only robust if it’s comprehensible to a Pascal programmer.

          However, if the SAP standard code in question is OO code, you so quickly get lost that you can rarely dream about understanding what it is doing.

          This is only the case if you’ve never got to grips with OO. As I’ve already stated, I’ve waded through plenty of SAP OO code – in BW and in the Web Dynpro runtime. I don’t have any difficulty.

          Your arguments seem to boil down to “I don’t get OO, I don’t understand it, therefore its bad”.  The fact is, even if you were right that OO is the worst thing to happen to programming since the GOTO was shunned 😈 , it is necessary already in many parts of SAP to be able to use it. If you want to get left behind out of a visceral dislike of the paradigm – go ahead.

          btw – FORMs are officially obsolete from 7.4.

          (0) 
          1. Suhas Saha

            FORMs are officially obsolete from 7.4.

            A small correction. Subroutines are obsolete modulrization technique since ABAP release 731 🙂

            (0) 
          2. Joao Sousa Post author

            btw – FORMs are officially obsolete from 7.4.

            And thank the lord for that. I’ve so many cases where the main program is very small, has an include for Z<whatever>_F01, and then 100 FORMs in the F01 program. God how I hate those….

            (0) 
      2. Simone Milesi

        A little OT

        Joao Sousa wrote:

        I don’t want fast programmers, I want robust programmers.

        In an utopic world everyone prefers robust programmers over fast ones.

        The problem is when you got the users/customers calling you 10 times each day for the program they required 🙂

        (0) 
        1. Joao Sousa Post author

          That’s when management comes in, which must filter the customer demands vs acceptable program quality. A good manager has to say “Wait a bit longer” to the customer, while the easiest “escape route” is “Yes sir, in two hour sir”. Manager who always say “Yes” aren’t real managers, are more like work forwarders.

          I always say to my teams, “I rather you take more time, and make it right” and I ask them to reevaluate their estimates when I think they are too low (which implies they are going to rush it).

          After many years I am pretty sure whenever you take shortcuts you end up paying for them, cause the customer will be pissed when finds the program riddled with bugs.

          (0) 
          1. Simone Milesi

            i agree at all, but in my (relative little) experience, i keep crashing against a wall when it comes up about method, discipline and timing.
            Just for a quick digression, it will deserve a specific thread.

            (0) 
            1. Joao Sousa Post author

              I don’t mean to say that I never do it, we are all humans, we all feel pressure and I have bosses myself. But you pay for rushing, that’s a fact.

              Just recently I had this situation, where I was on another project, going into holidays, so I didn’t review a button that a programmer added to a warehouse PDA screen. The customer wanted, I was formally assigned to other duties, and it slipped past review.

              What happened? I spent the next week and a half (while on holidays) getting mails from the customer about an issue that no one could replicate, and in the end it was this button which the programmer had added, in a rush, without validations or proper tests. If I had known how much time had been spent on the button, I would have been the first one to tell the customer “Wait a bit more”.

              If you’re not a manager you can’t really do much, you have to follow the deadlines that other people give you. The “I want robust programmer” is because I manage the deadlines internally.

              (0) 
              1. Simone Milesi

                i’m in the middle, as team leader, with someone giving me deadlines i keep fighting and a good team that help me (almost the time).

                So i feel literally between anvil and hammer, also because i understand BOTH requests (the users, my superiors and my mates).

                Another issue (but again, it’s alredy discussed before and another thread will fetch better since we are ot, shame on me!) is putting hands on old messy code: you can be the best developer on earth face, but each time you have to fingercross and hoping you analyzed well the existing code 🙂

                (0) 
                1. Joao Sousa Post author

                  Keep fighting the good fight 🙂 .

                  In a way your superior is your customer, so sometimes you will have to say: “It’s ready now with some risk attached … to be sure I need 1 more day”. When you’re in the middle that’s your job, your superior is probably the one that must make the risk based decision (and it’s ok if he takes it, sometimes we don’t have all the information).

                  (0) 
    1. Joao Sousa Post author

      They don’t really provide an explanation but I think it supports the arguments that the most important thing is to follow guidelines, regardless of the methodology.

      Maybe I find that breaking bad habits in ABAP by going OO, is the thing that is improving productivity, more so then the actual methodology.

      Unlike other business contexts, I find many ABAPers who do not have a formal training in Computer Science. Functionals that became technical people, people from management courses that became programmers, etc. OO provides a formal framework that they never had.

      (0) 
      1. Matthew Billingham

        Maybe that’s it – I do have a degree in Computer Science!

        Back when I was running development teams, we did a bit of research linking programming styles to Myer Briggs Type Indicators. It turned out that, fairly consistently, almost 90% of developers were clustered around one type (I forget which). These people were logical and analytical and got the job done. The other 10% were clustered around almost the opposite type. These were the intutitives, who appreciated the artistry in an elegant solutions. They were the ones the business liked to work with most because they could communicate with them! Their developments also tended to be more robust – once they were working, they stayed working even after enhancements. They were also the ones who surprised the MBTI experts – “why are you a developer – you’ve got the wrong type!”.

        I’d contend that it’s this 10% who’d favour the OO paradigm.

        (0) 
        1. Joao Sousa Post author

          I’ve done that test, but I don’t remember the outcome. I don’t think it really mattered, the company just did the survey in a workshop to make us know ourselves better.

          I’ll confess that I give a huge importance (more then I should) to aesthetics. In fact, since in ABAP for Eclipse warnings are visible in the editor, I’ve found that I’m much more likely so squash them, because they upset the “harmony” of the code.

          Seeing code that doesn’t follow guidelines hurts my senses almost as much as my logical reasoning. When I see that 300 lines method that should have been split …sniff….

          (0) 
        2. Gregor Brett

          So you are inferring that developers who favour the OO paradigm are almost the opposite of logical and analytical? 🙂

          This discussion was originally around using objects to encapsulate method parameters. My argument was that there is a line between elegance and over-engineering.

          While I appreciate and use OO I still think there are many cases where ABAP structures and function modules are the right tool for the job!

          (0) 
          1. Joao Sousa Post author

            While I appreciate and use OO I still think there are many cases where ABAP structures and function modules are the right tool for the job!

            And I think we all agree on that. We just happen to disagree on where to draw the line. 🙂

            (0) 
  6. Uwe Fetzer

    In the discussion thread often is mentioned, that you have to write a good documentation of your FMs and objects.

    I don’t want to force you to not document your code, but if your objects are well written, you don’t really have to read documentation.

    Example: Do you need to read a documentation (or the source code) of the ALV framework? No, because the classes and methods are self explaining.

    The most important thing I’ve learned for OO: keep the methods short (< 100 lines) + NO SURPRISES. If a method is called “check_xyz” no values have to be changed.

    (0) 
    1. Joao Sousa Post author

      When I’m writing the ABAP Doc the thing I find most critical to describe is the output parameter, and exceptions. Sometimes I don’t think I can make it clear enough by looking at the name.

      For example, if I have a method GET_SALES_ORDER from a delivery object, it may not be clear by the name whether it returns the object or the sales order number, and a lot of people in SAP are used to the latter. The exceptions are even more hard to describe only with the name.

      But I do agree completely that good naming saves you a lot of trouble with the documentation, and specially that last bit. If the method is called CHECK make sure nothing is changed.

      (0) 
      1. Uwe Fetzer

        GET_SALES_ORDER should always return the object (because SALES_ORDER is an object). Else it should be names GET_ORDER_NUMBER in my opinion.

        But you are rtight, it’s not everytime so obvious.

        (0) 
  7. Uwe Fetzer

    Jens:

    Here a couple of screenshots from ABAP in Eclipse which, I think, are self explaining. “Quickfix” (<ctrl> + 1) is the magic word:

    aie1.PNG

    Quick Fix

    aie2.PNG

    <enter>

    aie3.PNG

    <enter>

    aie4.PNG

    Voilá -> the cursor is placed where you can code on

    And if you want to see the method interface, you just have to press <f2>:

    aie5.PNG

    Just because you don’t know the solution it doesn’t mean, that there IS no solution.

    (0) 
    1. Jens Petersen

      Thank you for the screenshots. I see your point (even though it appears to require Eclipse), but perhaps with my 41 years I am getting too old for this. To me, fluent development means doing as much as possible with the keyboard and not touching the mouse if I can help it, seeing that alternating keyboard and mouse usage is always slower than only using the keyboard. Leaving the keyboard with your hand, grasping your mouse, locating the mouse cursor and then moving it to an input position so you can type (or clicking radio buttons etc.) is like a media break to me, like printing data in order to scan and OCR it afterwards. SAP has been moving into that direction for years, but I hate it because it makes me slower and interrupts my thinking which should remain focussed on the content, not on the interface.

      (And no, I am not unskilled with the mouse, rather the opposite as I am playing RTS games on a highly competitive level, but being skilled with the mouse does not mean desiring to use it when sticking to the keyboard is simply more efficient.)

      (0) 
        1. Manish Kumar

          It looks like the mouse bit was meant for Define Method Signature popup. It has radiobuttons and checkboxes. I guess pressing ALT key would have given key bindings for most of the options in that popup. SAP GUI is certainly lacks class-related features when compared to ADT/Eclipse.

          (0) 

Leave a Reply