Skip to Content

The issue perceived

Some developers have concerns about having too many classes affecting performance and maintainability.

Classes are a form of modularisation; in and of themselves, they have no significant effect on performance. It is in the use or implementation of classes that problems can arise.

What problems?

  1. Obsessions with pure object orientation
  2. Classes with too many methods and attributes
  3. Too detailed object orientation
  4. Designing objects for single use and not considering bulk actions. E.g. a class for handling materials – but then when a bunch of materials is needed, selecting each material singly, instead of select into table.

In my experience, ABAP Object orientation is more about considering the programming problems in terms of objects communicating with each other. E.g. userids, handlers (screen, database…), layers (MVC) – rather than traditional OO paradigm of “Everything is an object”. ABAP OO programming is rather different to most OO languages. Java, for example, has only a few programming keywords and basic types; ABAP is far richer and we should use that richness for our advantage.

Hit me with another class!

While too many classes can make an application overly complex, there are some scenarios that indicate you should be considering adding a class or two (or more).

  1. Your class is becoming complex and big
    1. Class is dealing with multiple conceptual objects
    2. Class is dealing with multiple responsibilities
  2. It becomes clear that there is scope for reuse for part of the class.
  3. Same code being used in two or more classes.
  4. Similar code is being used in two or more classes (add a class and use subclasses for the specialisation).
  5. Subclass where there are logical checks for a type.
    1. Similarly named methods
    2. CASE or IF..ELSE..(ELSEIF)… for different behaviour according to type, especially if it appears in multiple places.

Case study

Consider file handling. You might find you have many programs that read files from the user’s PC. Each program might have code like this:

DATA(extension) = me->get_file_extension( filename ). 
CASE extension.
  WHEN 'CSV'.
    me->read_data_from_csv( ).
  WHEN 'XLSX'.
    me->read_data_from_xlsx( ).
...
ENDCASE.

It makes sense in this case to create a class for handling files to take over common file handling tasks. In every program that needs to deal with files you could replace the above (and remove the specialised methods) with something like:

zcl_file_handler=>get_handler( file_name )->read_data( IMPORTING e_data = my_specific_data ).

Where file_name contains the full name of the file, the static method get_handler returns an instance of a file handler (factory pattern), and my_specific_data is an internal table with fields for the data I need.

There are many types of files that can be uploaded from the PC, e.g. CSV, XLSX… so you would subclass the file handler with a class for CSV files, and another for XLSX files, with the specifics needed to generically load the different file types.

In this case get_handler takes the file name and returns the correct subclass according to the file extension. In the subclasses, read_data (which should be abstract in the superclass), dynamically fills the table e_data correctly with the contents of the file. Of course, error handling must be in place to deal with incorrectly formatted files.

Note, that if you need to handle more file types, or change the way an existing file type is handled (e.g. moving from reading XLSX via OLE, and instead using some of the classes that directly handle XLSX), you don’t need to change any of the programs that use the file handler. Previously, you’d have to update each one, with all the effort and potential for mistakes that incurs.

Pragmatism

I’ve been programming using ABAP objects now for over 15 years. In that time, I’ve adopted what I consider a pragmatic approach to class creation

  1. Use classes to program in layers – UI, logic, DB etc. (Also known as separation of concerns).
  2. Make use of the richness of ABAP – e.g. consider internal tables as objects, with “methods” like READ, LOOP AT etc. Don’t create a class that emulates Java or C++ iterators. (See this blog for a more detailed explanation)
  3. Use private methods to prevent duplicate code being written within a class
  4. Use additional classes where indicated above
  5. Stuff OO if it gets in the way of simplicity or performance critical operations!
  6. Be very careful with the database access layer, that in the pursuit of object orientation, performance is not sacrificed. (One reason I no longer use persistent objects).

Tl;DR – Take home lesson:

Create a new class where it makes programmatic sense.

  • Properly designed developments are simpler, cheaper, more robust, safer to maintain and easier to test.
  • Don’t not create a class just because you’re worried about too many classes.
  • Don’t create a class for the sake of some programming philosophy.
  • Do study design patterns and use them where appropriate.

 

To report this post you need to login first.

12 Comments

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

  1. Simone Milesi

    Hi Matthew!

    Wonderful blog which clears many doubts about my approach to ABAP OO and opens way more! 🙂

    But i consider this nice because i love to reinvent myself anytime i find something usefu!

    Make use of the richness of ABAP – e.g. consider internal tables as objects, with “methods” like READ, LOOP AT etc. Don’t create a class that emulates Java or C++ iterators.

    This point leaves me a bit puzzled and i hope you’ll find the time to clearify me this point.

    i usually use methods to combine data from different object in a “main class” specific method, using a “READ/GET” one.

    i’m missing the design of a “LOOP” method: do you have any example? 🙂

    Anyway, wonderful blog!

    i hope it helps many others to see the light!

     

    (1) 
    1. Matthew Billingham Post author

      What I meant was don’t encapsulate internal tables. Don’t create a method for loop or read. Just handle them normally using the abap keywords LOOP and READ.

      Life is to short for ABAP internal table iterators!

      (2) 
        1. Matthew Billingham Post author

          Nah. I’m staying with methodology – because it’s a framework for program development, which to my mind is larger than simply “method”.

          The presentation here refers to TDD as a methodology.

          (0) 
          1. Lars Breddemann

            Yeah, that presentation is calling everything ‘methodology’ including the waterfall process.

            That’s probably the same line of thinking that gets ‘methodology’ on nearly every SAP slide deck: that it is something more or larger than just a method.
            That in turn, IMO, is doing the good old “method” not a favour. A “method” easily can describe how to set up a development process in a flexible way. It’s not necessarily a simple step by step instruction list or algorithm.

            And TDD (at least in none sources I’ve read so far) doesn’t go and analyse different methods of testing software. It’s actually pretty prescriptive about how the testing should occur (http://www.agiledata.org/essays/tdd.html):  Write a test, write the code to make the test pass, write another test… maybe I’m just missing the part where TDD is about testing methods?

             

            (0) 
  2. Michelle Crapo

    Perfect!

    I love that classes are used when appropriate – otherwise not.   Another quick way to see that a class is needed.   Take a quick look at your function group.   What are those function modules doing?   Would it make better sense to use class/method approach.

    Opposite – look at your class.   Does it make sense – per all the reason above.   You’ve made my day.  I get to leave now.  I’ve learned something.    Not really, but it would be nice.

    (1) 
    1. Matthew Billingham Post author

      I only use function groups for Table Maintenance. I see function groups as essentially static classes. Since (especially in later ABAP releases) calling class methods is neater than calling function modules, I prefer to use classes.

      But also, I don’t use static classes (and keep static methods to a minimum). Some of my colleagues don’t like

      DATA thing TYPE REF TO cl_thing.
      CREATE OBJECT thing.
      thing->do_something( ).
      
      

      Preferring to use

      cl_thing_handler=>do_something( ).

      If you use the first, that that means if you need to specialise later on, you can. I have in past created static classes – and nearly always had to convert it to instantiation later on.

      Even if you only need one object, then use the singleton pattern rather than a function module or static class.

      (2) 
  3. Jelena Perfiljeva

    This is really nice! I fully blame broken SCN content discovery for missing this when I was on vacation (judging by the date).

    I’m very much in favor of practicality when it comes to development and blogs like this are very helpful to avoid common mistakes.

    Honestly, I’d even love a deep dive for dummies into that zcl_file_handler. 🙂

    (0) 

Leave a Reply