ABAP Objects is the Way Forward – I Want to Believe – Part Three

http://scn.sap.com/community/abap/blog/2013/07/04/abap-objects–i-want-to-believe

http://scn.sap.com/community/abap/blog/2013/08/09/abap-objects–i-want-to-believe–part-02

 

  /wp-content/uploads/2013/10/image001_291158.png

 

 

   

Can you write OO     programs faster than procedural ones?

Or are there     technical roadblocks?

   

                           Figure One – In the Meadow we will build a snowman

The above blogs – first parts of this series – can be summarised as follows:-

·         I want to prove that writing new programs in OO really is better than the “old” way

·         I have a real life project which allows me to do just that

·         I am going to try to document how I go on this step by step

·         The example will be silly, but based on the real project

·         I have now started writing the prototype program in earnest

Now is the table of our contents

/wp-content/uploads/2013/10/image002_291159.png/wp-content/uploads/2013/10/image003_291160.jpg

Figure 2 & 3 – Table of our contents

·         (1) Status of my monster project

·         (2) Status of my OO Reading

·         (3) Creating a Monster Simulator

·         (4) Problems with writing Local Classes

·         (5) Writing Code Faster

·         (6) Monster Simulator Code + Screen Shots

Everything that follows will appear ludicrous at first glance, but I assure you it is all based on what I am actually going through in real life, with the names and nature of the project changed to protect trade secrets and what have you.

(1)   Status of my monster project

As we all know, Baron Frankenstein was chased out of Germany by a crowd of villagers waving pitchforks, and he now lives in Australia. After purchasing an out of the box monster making solution from SAP he was unhappy, and so commissioned me as an ABAP programmer to write his monster making program, using SAP VC. I was probably chosen because I worked in Germany for several years, right next to SAP HQ in Walldorf.

Baron Frankenstein is the project manager, based in Sydney, the executive sponsor is a member of the board (Vorstand) Count Dracula, and my primary contact is the Baron’s hunchbacked assistant Fritz (known as Igor) who works in a monster making laboratory in Brisbane.

My initial task is to write a proof of concept program, where you can enter monster attributes into SAP and a bill of materials (BOM) needed to make the monster which comes out the other end. This is based upon a gigantic spreadsheet created by Igor, in which he modifies the logic fairly radically at least once a week, sending me a new version each time.

In the past, when I did similar projects for The Creature from the Black Lagoon, for example, I always used procedural programming and stayed right within my comfort zone. However, whilst I was flying back from Germany to Australia mid 2012 a radioactive object orientated programmer went crazy on the plane and bit me, and when I woke up the next day I found a had an uncontrollable urge to learn how to write all my new SAP developments in an OO manner.

(2)   Status of my OO Reading

In my previous blogs I have included links to the vast amount of OO information that is available on the internet which I hungrily devoured. The good thing about reading all this now – 13 years after I started programming in SAP – is that the whole concept is far from abstract, I can try to relate it to what I do every day.

I have now finished both the books by Robert Martin – The Clean Coder, and Clean Code (the latter being the one I wanted) though to really get the point of the latter you have to go through the last bit many times to appreciate how he is making the example code better.

That was good, and I was going to go through the last bit ten times until I had got my head around it, but I got distracted by another book I bought which I am amazingly impressed with.

http://shop.oreilly.com/product/9780596007126.do

/wp-content/uploads/2013/10/image005_291163.png

Figure 4 – Head First Design Patterns

Once again this is all based in Java, and once again the similarity between Java and what you can do in the 7.02 version of ABAP is so close they might as well be identical.

This explains, using really stupid yet technically valid examples, not only HOW to program using OO principles, but a million times more importantly WHY they are good i.e. what practical benefit you get by writing programs this way, especially in the face of the ever present monster coming over the hill CHANGE.

In one of the comments on my last blog someone mentioned that in the book they were reading the sole purpose of OO programing was given as lowering costs. Can this be true? I am beginning to think that yes it is.

Here is what I did:-

I downloaded a sample chapter of this book for free

http://oreilly.com/catalog/hfdesignpat/chapter/ch03.pdf

The “heads first” part of the title relates to a psychological approach to designing textbooks which is supposed to be able to get information into your brain faster than the traditional long winded textbooks we are all familiar with i.e. it uses cartoons, and humour, and games, and redundancy (telling you the ame thing in various formats) and all sorts of non-traditional methods. I think it works a treat.

However, even given that, it is all very well to read a chapter and THINK you have understood it, but if you really want to be sure you have got the message, then try writing the same program for a different example in a different language (i.e. ABAP instead of Java in this case).

Then try explaining it to someone else i.e. writing a blog on the SCN. If you can’t explain something to anyone else it is likely you don’t understand it yourself. Conversely, if you can make jokes about the subject it is a clue that you do understand it. I like to think my below blog is an example of the latter.

http://scn.sap.com/community/abap/blog/2013/03/02/oo-design-patterns–decorator–in-abap

Even more importantly I did not just try to make a carbon copy of the example, I tried to see if I could improve it. Since the examples in that book are intentionally pared down to concentrate on just one aspect and not over-complicate and confuse the reader they (example programs) naturally are going to have room for improvement.

In my opinion at least that whole exercise worked so well in regard to ramming a new concept in my mind, I thought I would do it again, with every chapter in the book if need be, so I ordered the book from Amazon and it is sitting by my bed. Once I finish this series of blogs that is what I will return to, but I would encourage every single ABAP programmer on SCN who is interested in moving to OO programming to beat me to it, and do this exact same thing I just described.

As an aside, I just went on the internet to find the link to the book, and discovered that the model on the front of the book with the pigtails has used (or her advertising agency has used) the exact same photograph of herself to advertise a very different product, one not to do with IT but more related to personal hygiene. It’s a funny old world.

This diversion into OO books may seem irrelevant but I think it is anything but – every day at work when I get presented with the non-stop stream of complicated business problems to solve I can start to see the concepts in these books again and again, this time in a real life context.

This is like when I used the interactive audio course “Rocket German” to try and learn the language before I went to live there, and the very first day I was walking down the street and listened to people I could hear them saying the very things mentioned in the language lessons and I thought “this is not just a complicated game – it is actually real”.

In last weeks’ exciting episode…

If you look back to my first blog on this subject (link at the top of this blog) you will see that I had got as far as defining the test class first, and writing some tests, and only then defining the skeleton of the monster simulator class. Just enough to get everything to compile – with all the tests failing. Thus, test driven development.

/wp-content/uploads/2013/10/image007_291165.png

Figure 5 – ABAP Unit

That is all the program does thus far, runs a series of tests on an empty method in the class under test, which naturally fails.

(3)   Creating a Monster Simulator

See you later, Simulator

As mentioned earlier, all throughout this project the Baron and various other interested parties are going to be at me to see how far I have got. Failing tests are not going to impress them, and a blue line at the bottom saying everything has passed is not going to impress them, so in tandem with building the production code I want a simulator program which shows the application log saying what is happening in each step on the monster building process.

To make matters worse, in this imaginary story and in real life, the business users designing the monster algorithm cannot agree with themselves how they want to maintain the master data, or even what columns go in what tables. I am made aware of the current state of play by an ever changing spreadsheet with a very large number of tabs, each containing master data. Every so often a tab appears or vanishes, and the data in the tabs i.e. columns and even what constitutes a key field, keeps changing.

This is a typical programming situation – the users can’t agree on what it is they actually want, the specification is in a constant state of flux, and yet you have to start building the thing anyway. In a “waterfall” world this sort of thing would be stopped dead, but the argument would go that in such a case you would not get such a good result, as you would not have constant feedback from the users about the ever-changing amorphous shape-shifter of an application that is being built.

Custom Table Tennis

At first glance it would seem to that you can’t really build a proper simulator if you don’t know exactly what custom Z tables you will have, or even what exactly will be in them. They change so fast I am not even going to think about creating any Z database tables until things have calmed down, and that might be some time.

However in the world of unit testing you don’t use the real database either. You create a subclass “mock” of your real database access class and use that to give you back fake data. Since I am going to be using such a mock database class anyway, as the unit tests come before the production code, I might as well use it in my simulator program as well until such time as the business users come to a consensus on which way is up.

Mocks Blow – Shadmocks? Only Whistle

What is a “mock” you may ask?

According to the book “The Monster Club” by R.Chetwynd Haynes, a “Mock” is a monster that you get when you reach the third generation of different sorts of monsters mating with each other.

/wp-content/uploads/2013/10/image009_291167.png

Figure 6 – What is a Mock?

Some people argue that in a programming sense a mock is a class that imitates the behaviour of another class without actually going to the database or whatever.

OK, lets’ create empty skeletons of the real database access class and its mock friend.

CLASS lcl_pers_layer DEFINITION.

ENDCLASS.

CLASS lcl_mock_pers_layer DEFINITION INHERITING FROM lcl_pers_layer.

ENDCLASS.

We now have to be able to pass the mock object into our class under test (monster simulator) when it gets created.

CLASS lcl_monster_simulator DEFINITION FINAL FRIENDS lif_unit_test.
 
PUBLIC SECTION.
   
DATA:    mo_pl            TYPE REF TO lcl_pers_layer.

    METHODS: constructor IMPORTING io_pers_layer TYPE REF TO lcl_pers_layer OPTIONAL,

CLASS lcl_monster_simulator IMPLEMENTATION.

  METHOD constructor.

    IF io_pers_layerIS NOT INITIAL.
      mo_pl
= io_pers_layer.
   
ELSE.
     
CREATE OBJECT mo_pl.
   
ENDIF.

  ENDMETHOD.                    constructor

The usual purpose of such a fake class is just for use in unit testing. Normally the fake does not get passed in when the object is created and so the real database access class is used in productive code.

CLASS lcl_test_class IMPLEMENTATION.

  METHOD setup.
*——————————————————————–*
* Called before every test
*——————————————————————–*
   
CREATE OBJECT mo_mock_pers_layer.

    CREATE OBJECT mo_class_under_test
     
EXPORTING
        io_pers_layer
= mo_mock_pers_layer.

    CREATE OBJECT mo_class_under_test.

    CLEAR: ms_input,
           ms_output
.

  ENDMETHOD.                    setup

I create an executable program for my monster simulator, with a transaction code and a selection screen, and then in a procedure I just do exactly the same as I am doing in the unit test.

FORM make_monster .
* Local Variables
 
DATA: lo_simulator   TYPE REF TO lcl_monster_simulator,
        lo_fake       
TYPE REF TO lcl_mock_pers_layer,
        ls_input      
TYPE g_typ_monster_input_data,
        ls_output     
TYPE g_typ_monster_output_data,
        lo_error_log  
TYPE REF TO zcx_general_error.

  “When we get to the stage we actually have database tables, we will
 
“stop using the fake, then the fake will only be used for unit tests
 
CREATE OBJECT lo_fake.
 
CREATE OBJECT lo_simulator
   
EXPORTING
      io_pers_layer
= lo_fake.

  “Pass in Parameters from the Selection-Screen
  ls_inputmonster_strength  
= p_stren.
  ls_inputmonster_brain_type
= p_brain.

  TRY.
      lo_simulator
->assemble_monster(
   
EXPORTING id_monster_strength   = ls_inputmonster_strength
              id_monster_brain_type
= ls_inputmonster_brain_type
   
IMPORTING ef_madness            = ls_outputis_monster_mad
              ef_creator_alive     
= ls_outputis_creator_alive ).
   
CATCH zcx_general_error INTO lo_error_log.
      lo_error_log
->error_log->show_error_log( ).
 
ENDTRY.

ENDFORM.                    ” MAKE_MONSTER

At the moment that seems pretty pointless. That is because we have not added in the important thing that the simulator program is going to do which the unit tests most definitely are not going to do, and that is to show a detailed application log of every step in the monster making process.

You can’t send anything to the screen during a unit test, nor would you want to, you get an error message. However there is nothing to stop the production code merrily logging everything that happens. The unit test methods ignore this log; the executable program will show it to the user.

DRY / Extractions

In order not to give away any trade secrets I can’t show code samples and screen shots from the real application I am building, so I have to build the monster making application in tandem, which does the same sort of thing but with all the domain names changed to monster based ones.

So I am writing two programs at once, one to make what my company wants to make, one to make monsters for the Baron. Because one is intended to demonstrate how the other works they naturally are going to be as similar as possible with just the nature of the variables and the algorithm itself being different.

The DRY principle stands for “don’t repeat yourself” so every time I find myself writing the exact same line of code in my monster program as in my real program I should start to try and follow the core OO principle of “separate the things that vary from the things that stay the same”.

In my day to day job whenever I see two chunks of custom code exactly the same, whether it bein an OO or a procedural program, I aim to extract them to a common function or method. The two barriers here are the ever popular “but it works as it is, don’t change anything at all unless it’s broken” and “but it is so EASY to just cut and paste the code”. The latter is the biggest problem, people are lazy by nature, I am no exception I have to force myself to do things the hard way, because I know that if you start off with ten identical chunks of code after about ten years you end up with ten slightly different versions of that code.

Just yesterday my colleague was investigating some bizarre workflow behaviour. It turns out that two years ago someone had the job of removing a check for a certain type of error, as this was no longer considered an error. The problem was there were about six different places where the error check routine was. Four of these were detected and changed; two went under the radar and remained the same. So, sometimes the error check was invoked, sometimes it was not, seemingly at random. If the error check had been in its own function it would have been impossible for this problem to have occurred.

I wrote a local logging class for my real application, and then I need to show it in the monster making program, so I can show a screen shot of monster making steps as opposed to a log of trade secret squirrel steps. I could just copy the vast block of code from the real program to my example program, but above I said whenever I found myself doing that then lights will start to flash and music play in my head and a giraffes head will shoot out of the computer screen and bite me, all clear warnings that I need to extract that code into a re-usable Z class.

(4)   Problems with writing Local Classes

Go Z Young Man

/wp-content/uploads/2013/10/image010_291168.png

Figure 7 – ABAP Development Team

This brings me to a comment someone made about one of my earlier blogs along the lines of why bother to create local classes at all given that the ABAP editor has such poor support for them compared with Z classes.

I have complained about this a million times before, and now I am going to do it once again, a clear violation of the DRY principle.

As an example, I create a (local) definition of my monster simulator class in the CD01 include, and manually create an implementation in the CI01 include.

I then go back into the definition include, write some more code and then try and double click on the class name in the definition to branch to the implementation. The system tells me no such implementation exists, and I am used to that from procedural programming so I think “oh I must not have created it yet” so I accept the systems kind offer to create the implementation for me.

It does, all well and good.

*&———————————————————————*
*&       Class (Implementation)  lcl_monster_simulator
*&———————————————————————*
*        Text
*———————————————————————-*
class lcl_monster_simulator implementation.

endclass.               lcl_monster_simulator

The only problem of course is that the implementation does in fact already exist. Now if I did a syntax check, it would complain that there were two implementations for the same thing.

When writing a procedural program I generate all my FORM routines by writing the call first i.e. PERFORM SUCH_AND_SUCH CHANGING SOMETHING, and a skeleton of the FORM routine is magically created for me complete with the signature. I have to manually add the types of the variables even though the compiler knows them but that is small potatoes in the grand scheme of things.

In OO world I have to create all such things manually, and then I manually add comments saying what the signature is – in procedural world you get automatically generated comments saying the signature, which you don’t need as you can see the signature, in OO world the reverse is true you can’t see the signature in a method implementation of a local class, and you don’t get the generated comments either. This is known as “feast or famine”.

Ever since 4.6 the official position of SAP has been they want us to switch to OO programming, but this sort of thing does not make people rush forward. If you are going to change people’s mindset the programming tools need to be AT LEAST as good as the ones they had before, not ten times worse. The analogy would be I want people to but the new car I have invented, it runs on water, and can fly, but I forgot to add an ignition key so you have to start the motor by inserting a hand crank in the front and then turning it round until the engine catches, and then I forgot to add doors, so you have to get in by crawling underneath and squeezing in through a hole in the bottom of the car.

The counter argument I get is “oh well, in ABAP in Eclipse you can do just this, create skeletons of implementations, almost as good as you could in ABAP ten years ago”. Fantastic, except you need the latest version of Netweaver, and I’m not going to have that for five to ten years (I’m on ECC 6.0 EHP5), and according to Back to the Future Part Two, we will have flying cars by 2015 so I will have been flying to work for years before I can use ABAP in Eclipse.

Secondly, according to all the blog comments whenever someone from SAP posts a blog about this subject most of the audience start waving blazing torches and attack the blogger with pitchforks, saying how dare you make us move away from SE80.  I said Eclipse was good in a blog once, and don’t I wish I hadn’t, I have never got so much abuse in all my life.

So, in my dream I went to SAP development in Waldorf and asked when they were going to make programming local classes as easy as writing a procedural programming, and while you are at it, can we have some sort of non-browser based UI for SAP, just as fast as SAP GUI, but without all the hacks and workarounds you need to make DYNPRO screens work with OO programs? This was the response:-

/wp-content/uploads/2013/10/image011_291169.png

Figure 8 – SAP Response to Development Request

That was wonderful, there is nothing like a whole heap of moaning and whingeing to get a weight of your chest. I’d like to ask the panel if I am alone in this, does anyone out there think writing local classes is as easy or easier (by this I mean faster) than the procedural equivalent? Hopefully I am missing something obvious and someone will post a comment saying “pull that branch on that tree over there three times” and all my problems will be solved.

(5)   Writing Code Faster

SE80, You Can Sail the Seven Seas

The whole last section was a divergence down a rabbit hole based on my statement that I was going to turn a local class into a Z class, which got me thinking about how difficult local classes are.

Am I going to get back to the main point now? No, it is time to go off down another street, rather like Scottish comedian Billy Connolly does when giving a concert. He always gets back to where he started eventually, and so will I, but for now, let’s expand on the subject of writing in method implementations by hand to all the other non-value adding things we do by hand every day.

I am forever grateful to Thomas Jung for getting the new ABAP editor back-ported to version 4.7 so I could start using it years before I got to work on an ECC 6.0 system. I feel the same way about the workflow user group who forced SAP to add the new ABAP editor to the BOR transaction SWO1. The automatic code completion, and being able to ask for possible component values in a structure and then choosing what you want, are such incredible time savers, I imagine worldwide SAP developer productivity went up dramatically.

I wonder if the very people who are horrified at the prospect of ABAP in Eclipse know where the idea for all these new ideas i.e. colouring of keywords, code completion etc. came from? Maybe they will never know.

Robert Martin once wrote about setting up his computer to record his screen whilst he programmed to see what he spent the most time doing. In his case it was paging up and down, I wonder if I did this exercise on myself I would find I spent three quarters of my time doing non-programming type things which are sometimes needed for technical reasons, and sometimes just for my OCD need to have things look pretty.

Pretty Printer, with sugar on

As long as I have been programming in ABAP (I started about 1997) there has been the “pretty printer” feature in the ABAP editor which means you don’t have to manually line up the start and end of IF statements and the like. I find whilst I am programming I press the “pretty printer” button just before doing the syntax check, which is about once every two to three minutes throughout the day.

However, there are still some things you need to manually line up, if you so desire. A company that spotted a gap in the market here is Hovitaga http://www.hovitaga.com/ who came up with an add-on to the pretty printer. Go on, download it – itsfree – and see for yourself.

For example, when I am busy creating a big TYPE declaration, I do not know at the start how long the longest component name is, and I can end up with something like this:-

TYPES: BEGIN OF ty_hovitaga_test,
  thing
TYPE vbakauart,
     other_thing
TYPE vbakvbeln,
  yet_another_thing
TYPE likpvbeln,
and_another
TYPE msegmblnr,
END OF ty_hovitaga_test.

I then go through each line and manually line everything up. After I install the add-on, the pretty printer does this for me.

TYPES: BEGIN OF ty_hovitaga_test,
         thing                    
TYPE vbakauart,
         other_thing          
TYPE vbakvbeln,
         yet_another_thing
TYPE likpvbeln,
         and_another         
TYPE msegmblnr,
      
END OF ty_hovitaga_test.

That saves a minute or two every so often and really every second counts, especially on these housekeeping activities.

Some people when they install a free add-on like this or ABAP2XLS just think “that’s good” and use it as a back box, but other people like my good self cannot help having a peek inside to see how it works and then of course “improving” (or at least fiddling with) it, to see if it can do some other things we want.

For example, I might to like automatically align statements like this:-

mo_logger->add_calc_log_entry( id_input1  = ld_old_monster_dsgn
                          id_input2 
= ls_blood_volumesvolume
                          id_formula
= ‘&V1& – &V2&’
                          id_output1
= ld_new_monster_dsgn ).

Such that all the equalssigns are under each other. Not everyone cares about things like this but I often find myself manually aligning such code.

I want to get to the stage whenever I find myself doing the same mundane task over and over during the day like manually lining things up or cutting and pasting a signature into comments or something, I ought to think to myself – hang on, do I really need to do this, and then look at alternatives like:-

·         Enhancing the Pretty Printer as above or

·         A custom pattern or

http://scn.sap.com/community/abap/blog/2010/11/03/call-a-function-module-in-the-abap-editor-stop-crying–start-laughing

·         A macro

http://scn.sap.com/community/abap/blog/2012/10/28/use-macros-use-them-wisely

We spend our days writing tools to help business users do their jobs more efficiently, the least we can do is the same for ourselves.

OK, time to come out of the rabbit hole, and back to the monster making program.

(6)   Monster Simulator Code + Screen Shots

Captains’ Log

I had a local logging class, just an extension of the CL_RECA_MESSAGE_LIST, with a bunch of methods added to do assorted things with text and stuff them in the right place in the application log, in a nice hierarchical structure. There is nothing in there that has not been mentioned in many excellent blogs on this subject on the SCN so there is no point in me going into detail here. The important point is I moved my local class into a Z class with no application specific code at all, so I can use it all over the place.

I declare my MO_LOGGER object as an instance attribute of LCL_MONSTER_SIMULATOR and do a CREATE OBJECT in the constructor.

As an aside, having this at the start of my code causes huge problems:-

REPORT z_monster_maker_simulator.

INCLUDE z_monster_maker_simulator_top.

That stops the syntax checker working – you just get the “report is an INCLUDE” error message. You have to change the code as follows:-

*&———————————————————————*
*& Report  ZVC_MONSTER_MAKING_SIMULATOR
*&
*&———————————————————————*

INCLUDE z_monster_maker_simulator_top.

*&———————————————————————*
*&  Include           Z_MONSTER_MAKER_SIMULATOR_TOP
*&———————————————————————*
REPORT z_monster_maker_simulator.

Thereafter everything works fine.

My spreadsheet with the business process is based on a VISIO diagram. I have each big square on the VISIO diagram as a main process.

METHOD assemble_monster.
**——————————————————————–*
*    EXPORTING id_monster_strength   = ms_input-monster_strength
*              id_monster_brain_type = ms_input-monster_brain_type
*    IMPORTING ef_madness            = ms_output-is_monster_mad
*              ef_creator_alive      = ms_output-is_creator_alive
*——————————————————————–*

    mo_logger->main_process( ‘DIG UP BODY’ ).

    mo_logger->main_process( ‘STEAL BRAIN’ ).

    mo_logger->main_process( ‘PUT BRAIN IN MONSTER’ ).

  ENDMETHOD.Assemble Monster

Then each square gets split up into one or more sub-processes, which will have its own private method (which I am not supposed to test, so I have been informed). Inside the sub-process method will be a series of steps, which can be either a database read, or a calculation.

Since my variables are going to appear on the screen a user sees and I want F1 help and F4 drop downs where appropriate, I would like custom Z data elements. I force myself to do this by having my logging methods dynamically query the variables using run time identification to get the names of the data elements.

* Local Variables
   
DATA: ld_graveyard          TYPE zde_graveyard,
          ld_brain_weight      
TYPE zde_brain_weight VALUE ‘5’,
          ld_hunchback_capacity
TYPE zde_hunchback_capacity VALUE ’20’,
          lf_can_carry_brain   
TYPE zde_can_carry_brain.

  mo_logger->sub_process( ‘BREAK INTO GRAVEYARD’ ).

    mo_logger->process_step( ‘GET CORRECT GRAVEYARD’ ).

* Query database, a mock object will return a fake value
    ld_graveyard
= ‘Graveyard for Lunatics’.

    mo_logger->add_db_read_log_entry( id_input1  = id_monster_brain_type
                                      id_output1
= ld_graveyard ).

    mo_logger->process_step( ‘CALCULATE IF HUNCHY CAN CARRY BRAIN’ ).

    IF ld_brain_weight LE ld_hunchback_capacity.
      lf_can_carry_brain
= ‘YES’.
   
ELSE.
      lf_can_carry_brain
= ‘NO’.
   
ENDIF.

    mo_logger->add_calc_log_entry( id_input1  = ld_brain_weight
                                   id_input2 
= ld_hunchback_capacity
                                   id_formula
= ‘IF &V1& <= &V2& THEN YES’
                                   id_output1
= lf_can_carry_brain ).

I have limited the above example to one database read and one calculation, with some values coming out of nowhere as I did not see the point of showing the code for repeated database reads. At the moment the database read class is a fake (mock) class as we don’t know what database tables we are going to use in real life yet.

And it goes like this…..

/wp-content/uploads/2013/10/image012_291173.png

Figure 9 – Selection Screen

/wp-content/uploads/2013/10/image013_291174.png

Figure 10 – Application Log

I then say to the project manager, or anyone else interested “just run the simulation transactionin the sandpit client whenever you feel like it, and you will see how far I have got in implementing the algorithm”.

If lots of interested parties are looking at this all the time, then hopefully I will get a constant stream of feedback if I have implemented the algorithm wrong, or if they decide that they don’t like this algorithm after all and it needs changing.

Break Point

I think that about does it for this blog.

You Have Been Watching

·         1) Status of my monster project

·         (2) Status of my OO Reading

·         (3) Creating a Monster Simulator

·         (4) Problems with writing Local Classes

·         (5) Writing Code Faster

·         (6) Monster Simulator Code + Screen Shots

Next Steps

As my project advances in real life, I will mirror what actually happens in my monster making story. Hopefully this will dovetail nicely with all the reading I am doing on OO development.

When that’s all over I will start a new series on unit test enabling legacy programs. I am doing a talk on unit testing next March in Melbourne at the Mastering SAP Technology conference. The feedback I got from the Australian committe who choose what presentations get the green light seems to suggest an alarming number of SAP people have never heard of the ABAP Unit Framework.

After that, I will continue with what I described near the start of this blog, going through the designs patterns one by one in ABAP. So, this will keep me busy for the next few years!

I still consider myself a beginner in the OO world, there is a long road ahead….

/wp-content/uploads/2013/10/image014_291175.png

Figure 11 – The Road Goes Ever On

Cheersy Cheers

Paul

Subsequent blogs in this series:-

http://scn.sap.com/community/abap/blog/2013/10/29/abap-objects–iwtb–part-04–the-curse-of-frankenstein

To report this post you need to login first.

6 Comments

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

  1. Chris Paine

    Lots of love for this Paul 😘 – you’re putting the rest of us to shame 😉

    Really like your logging tool – kinda like the ability to show what is happening inside a BRF+ thingy (was looking for the word but it just wasn’t springing to mind). Actually to that point, since Igor loves playing with the formulas so much have you perhaps introduced him to BRF+? Although may still not be the ideal tool for business henchmen.

    Have you thought of making your add_calc_log method take in an array of variables? Or is Igor not that creative with his formulas?

    Brilliant blog, I look forward to future installments.

    Chris

    (0) 
    1. Paul Hardy Post author

      I love the idea of BRF+ in 2011 I spent every lunchtime at the German beer Garden reading the SAP Press book on the subject.

      I introduced it to my colleagues in Australia, one of whom uses it all the time instead of new Z customising tables. I have done one or two, but I am not sure BRF+ is quite there yet. The user interface is Web Dynpro, so it is ugly (like most Web Dynpro applications it is browser based lipstick on an SAP GUI pig) and slow (big whirling cicrle for a while after every input) and we have not managed to get SSO working for Web Dynpro applications yet so BRF+ is the only SAP thing I have to enter my password for.

      I am also not sure it is easy enough for business users to maintain data yet. However I have high hopes for this product, it is still evolving rapidly, hence the millions of OSS notes in each support stack, a lot of which increase functionality.

      I a considerign an array of input variables for my logging thingy, but I can’t think of a way to do this with less lines of code than in the example above. do you know of any examples of methods which take an arbitary amount of input values?

      I would like something like the SQL command SELECT WHERE BUKRS IN (‘001′,’002′,’003’) which takes a random amount of inputs.

      Cheersy Cheers

      Paul

      (0) 
    2. Paul Hardy Post author

      Every time someone at work asks me “is it possible to do that” I can’t stop until I’ve made whatever it is possible, especially if one of my colleagues has claimed it is impossible.

      In this case we want to pass in a variable amount of values, without having to declare an array and then fill it up.

      I just wrote a little test program where I defined a class which had some data and an instance variable of the same class as itself.

      Then I gave this class a factory class method where you pass in the data and get back an instance of the class.

      DATA: lo_recursive_thing TYPE REF TO lcl_recursive_thing.

      CREATE OBJECT lo_recursive_thing

        EXPORTING

          id_st = ‘String One’

          io_rt = lcl_recursive_thing=>get_thing(

          id_st = ‘String Two’

          io_rt = lcl_recursive_thing=>get_thing(

          id_st = ‘String Three’ ).

      If my recursive thing was an obect which held the details of an input parameter I could pass into my logging method as few or many values as I liked into a single input parameter of the class type “recursive thing”.

      Once inside my logging method I could then call a single operation on the object that was passed in and it would “unpack” itself, rather than me calling the same method repeatedly on each of the fixed input parameters.  This is a variation on the decorator method as I understand it.

      Hip Hip Array!

      Unpacking…

      METHOD print.”of lcl_recursive_thing

        IF md_string IS NOT INITIAL.

          WRITE:/ md_string.

        ENDIF.

        IF mo_predecessor IS BOUND.

          mo_predecessor->print( ).

      ENDMETHOD.

      Then after the LO_RECURSIVE_THING has been set up above I just call

      lo_recursive_thing->print( ).

      and out comes

      String One

      String Two

      String Three

      If there is a better / simpler method to do the same I am all ears….

      (0) 
  2. Matthew Billingham

    I have the Design Patterns book as well – and strongly recommend it. With any OO project, getting the design right in the first place saves a lot of effort.

    Having programmed Java in eclipse, I was quite amenable to using it for ABAP, but couldn’t see that it would be that much better than using the new editor in SE80. Then I got to play with it at a HANA course… I’m totally converted. I want my eclipse and I want it now. (Apparently, one of my clients will be upgrading in a few months, so I can have it then – for die hard SE80 enthusiasts, you can have SE80 in an eclipse window).

    I have used local classes a few times, but only to deal with data that truly is specific to the global class I’m constructing. And “main” classes in reports. But otherwise, it’s global classes all the way for me. I’m regularly finding I’m re-using that one-off global class I created 2, 3 or more years ago.

    (0) 

Leave a Reply