Skip to Content
Author's profile photo Paul Hardy

Back to the Future – Part 01

Summary

I find myself with a very complicated problem to solve, a problem I suspect many companies have run into in the past. It is going to take me a very long time to solve it, and whilst I am doing so, it occurred to me to share the process on SCN as that way I can hopefully

  • provide guidance to the less experienced programmers as to how to solve assorted problems.
  • get some guidance from the more experienced programmers as to whether my proposed solutions are a good way of solving the problem

I am going to try to do this in the belief that this is what SCN is all about – the giving and receiving of knowledge, with everyone winning in the end.

Background

The Australian part of my company went live with SAP in the year 2000. Our solution incorporated a large amount of ABAP programs which served as “front ends” to the business users, hiding the underlying complexity of SAP.

Since that time we have added an enormous amount of extra functionality to these programs.

In 2008 the company got taken over, and a decision was made by our new owners to migrate a large chunk of these programs into their existing SAP system, very flattering in a way. Initially only one country would make use of these programs – the United Kingdom – but in the long term all countries in the group (circa 70) would be using them.

So, for the last three years I have been working firstly in the United Kingdom (i.e. where the target users are) and then in Germany (i.e. where the head office is, and thus the development team) to copy over the programs from the Australian system and modify them for use in the UK and beyond.

All is now well, the UK is live, and I am currently en route back to Australia. The good news is that the UK users are happy bunnies, and head office is merrily planning the next rolls out in the USA, India, the rest of Europe etc..

However, being human, I am never satisfied.

The problems that I see looming are as follows:-

  • Currently there are two development systems – one in Australia, one for the rest of the group. One day – it could be five years away, but the day will definitely dawn – the desire from above will be to merge the two development systems
  • So, as the moment there are two versions of the programs, one in each system. Huge efforts have been made to keep them aligned, but the current feeling is that this is more or less impossible. The divergence will only increase over time.
  • When the next countries come on line they will want some changes made for “legal reasons” (which usually translates as “there is no such law, but we have always done it this way”). So “some changes” translates to “an enormous amount of changes per country”.
  • What I want to avoid at all costs is to have 70 different versions of the program, which all contain the same ten thousand lines of identical code, plus ten thousand lines of country specific code.

Going back to how such a divergence can occur in the first place, some people might say “that’s easy to avoid – whenever you make a change in one system, make the same change in the other”. That is easy technically, but not politically. The copied program is working fine in a live environment. The target program where loads of changes were being made was not in a live environment. The country with the live environment was very reluctant to have any changes made that might risk the productive system, especially as there was no gain except the nebulous “it is the right thing to do technically” statement. Now we have two live environments, so both sides feel the same way.

As a side issue, when we went live in the year 2000 we were on version 4.5 of SAP, and we did not really take advantage of any of the new technology when we went to 4.7 so a lot of the programs would be deemed “old fashioned” by a lot of the SCN community e.g. very little object orientation as ABAP objects just was not there in version 4.5.

Australia has only just upgraded to ECC6.0 EHP5 from 4.7 and head office is upgrading to the same level at the end of the year. So, when I back in Australia next month it will be my first time programming in an ECC6.0 system, apart from some very minor dabbling in PI.

I have kept up with all the latest information on SDN, attended conferences and inside tracks, and read assorted SAP textbooks about all the new technologies that have come in since 4.7 but I have never had the chance to use any of them for real. This makes me feel somewhat “left behind”.

So, when I get back to Australia I will of course have my real job to do, but as a hobby I am going to re-engineer an existing program – a great big incredibly complicated monolithic one. I want to use the :”think big, start small” approach, starting really simple and adding functionality one small bit at a time. As I mentioned earlier there is no time pressure on this so I have the luxury of being able to try out lots of thins in an attempt to get it “done right:, as opposed to “done fast” often a horrible trade off one has to make.

I could have chosen a simple ALV report, but where is the fun it that? I wanted a challenge so i wanted to pick the most complicated thing I can find. I wanted a “Venus De Milo”.

Venus De Milo

There is a famous IT proverb about how when a programmer first completes a program it is a thing of beauty, just like the Venus De Milo. The architecture is simple and elegant, it does everything the user wants, everyone is happy. Then as the years go by, extra requirements come in the door one after the other, lots of different programmers work upon your masterpiece, there is never enough time to look at the “big picture” and so workarounds are thrown into the pot, and before you know it the Venus De Milo now has twenty three arms and a Giraffes head sticking out of her chest.

That’s the sort of thing I wanted, so I could break it down and totally re-assemble it a la the film “The Fly” and it was easy enough to find an example in our system. The program I have chosen was created in 1997 and has been worked on by dozens of people ever since, and under the hood looks like nothing on Earth. When it was copied to the new system and the German developers took a look, to say they were puzzled was an understatement.

“Why did you do it like that?”

The answer could be, for example, that a certain section of code was done in a certain way to accommodate a complex business requirement which in the end turned out not to be needed. Nothing was ever documented – naturally – and nobody had the time to change the code back, so now we have complicated IF / THEN / ELSE blocks checking for things which once were presumed might occur but actually never did and never will.

So, in conclusion, that is what I am going to do. Shove a very old monolithic program in the matter transmitter, break it down into it’s components, and re-assemble it using the latest technology and a design based on OO as opposed to procedural. The only difference is that this time I am starting with something that looks like a human body but with a fly’s head on top and a giraffes head sticking out the middle, and hoping the end result is something that looks a bit better.

In an excellent book by Thomas Jung he creates an imaginary situation where a programmer finds himself having to use all the features that have just been added to SAP Netweaver. In a similar way I have made a great big list of things that were not available in SAP back in 1997 and made a provisional mapping to parts of my chosen application.

One small section at a time I will present one or more proposal of how I think I should implement a particular functionality, focusing on a “new” technology and I am hoping to get some feedback saying “you are mad – you should do it this way, and here is why” or – not very likely  – “yes, you are right” or  – best case – a huge debate will ensue online.

Aims for the exercise

Aims – Personal

  • To become familiar – in reality as opposed to in theory – to the new features in ABAP introduced after 4.7
  • To hopefully provide guidance to less experienced programmers on the SCN as to how to solve assorted problem
  • To hopefully receive some guidance from more experienced programmers on the SCN as to whether my proposed solutions are a good way of solving the problem, or the ravings of a madman
  • To have made enough progress and got enough feedback by August of this year to be able to give a talk about this concept at the annual SAP conference in Australia

Aims – Application

  • To ensure the same program can be run in different countries and respond differently according to local business needs, as opposed to creating 70 half-clones
  • To separate the “things that change” from the “things that stay the same”. Does that sound familiar?
  • To cater for the fact that ten different people are likely to be working on different parts of this program, all at the same time. Forever.

Aims – Technical

  • To unit test enable what is clearly legacy code
  • To move from a monolithic to an object orientated architecture
  • To eventually create both running versions of the program with the new one, with no loss of functionality. Difficult technically, maybe impossible politically, but I can but try.
  • As part of the above to be able to prove there is no loss of functionality by a combination of unit tests and HPQC tests (we have a full licence for that, which is a good thing).

The End is Nigh

I will end with two examples of some proposed new ways to achieve a given function in the current application with a method that is better – i.e. one or more of the following

  • simpler
  • more readable
  • more robust
  • more maintainable
  • more extendable

Example One

Doing a goods issue for a delivery is a technical step and you would expect it to be the same worldwide. Printing a ticket for the customer though, you would expect that printed output to look different in every single country. For example, from looking at what my German colleagues were working on recently some Eastern European countries you have to print out fifty four million different legal paper forms for each delivery, whilst some countries are moving to accept digital documents, where the customer signs on an IPAD or something. Anyway, the point is every country is different.

I thought about this, and I would propose a solution as follows:-

OO Example.JPG

Then the core “model” part of the application can say:-

LO_DELIVERY = ZCL_DELIVERY=>GET_BUSINESS_OBJECT( LD_VBELN ).

The correct sub-class will then be returned based using LIKP-VKORG as a starting point to find out the country. I’ve already got this working in an actual SAP system.

Then, later, when the core model program says

LO_DELIVERY->PRINT_TICKET( ).

The correct ticket format gets printed out, even though the method is implemented totally differently in each country. The application model does not need to be changed when you add a new country or change an existing one.

This seemed like a logical solution to me – however the question I would ask is – have I missed something totally obvious? Does the solution I propose make any sense at all, or is there a clearly superior solution which is staring me in the face?

Example Two

In my application the data in the main internal table is always the same, but the ORDER in which the fields appear in an ALV output, and indeed which fields are suppressed, varies according to the nature of about three or four fields which get input by the user on the selection screen – it would be really confusing if I explained the exact details of how the decision is made, in essence it is to do with the product and what the user is trying to do and it is SO complicated – but how to go about setting up the ALV field catalogue?

In the application as it is now, it works fine, but when one new developer saw how it worked – ten years ago – he was physically sick. It is basically a never ending series of IF / ELSEIF statements.

If (complicated set of conditions)

PERFORM add_field USING ‘LIKP’ “VBELN’ hotspot new_length etc

PERFORM add_field USING something else etc

dozens more lines

ELSEIF (another complicated set of decision)

the same sort of thing, with different fields in different order

etc….

As there are loads of fields in every case and one line of code to add each field, the code goes on for ever and is totally unreadable. There has to be a better way. You might wonder why the common fields are not added first before the conditional processing, but the problem is that the display order is totally different in every case. Sometimes the key field is even different. Naturally the display order is also changing all the time. What was vital in 2007 is redundant in 2010 etc. Oh, and in Australia “they” don;t want users to be able to store user-specific variants (though in the UK that is a requirement).

I thought of three ways to do this without a never ending string of IF statements:-

  • Define a sub-class for each situation, which redefines a method to say what fields need to be added
  • Create one or more Z tables, with key fields based on the fields that influence the decision, and then store the field order
  • As the rules are quite complex, I was wondering if BRF plus could be appropriate in such a situation? I have been reading the SAP press book on the subject every lunchtime in the beer garden near work in Germany for the last few weeks, and the “decision table” option described sounds like a possible fit.

So, once again I would ask – are any of these a logical way forward, and if so which one is the best? Or is there a much better, much more obvious way?

That’s all Folks

In my next blog I will start with what has already been done so far in order to keep programs in line between the two SAP systems despite the many differences between customising, business process etc, and then move on to comparison between the way certain functionality is implemented currently and some proposed new ways.

I wait with some trepidation for any feedback, I have found in the past it can get quite nasty!

Cheersy Cheers from Moscow,

Paul Hardy

Updates

2013/07/07 – It is fourteen months since I wrote this blog post, and I have come a long way on my understanding of OO programming, though it is a long had slog. I have managed to get myself in a position where I do the vast bulk of the maintenance work on the main application I describe above, and I am very slowly changing it into a state where it is more universally portable, and testable.

The blog below describe this very slow journey in some detail…

Related Blog Posts

Subsequent blogs in this series:-

http://scn.sap.com/community/abap/blog/2012/05/09/back-to-the-future–part-02

http://scn.sap.com/community/abap/blog/2012/05/30/back-to-the-future–part-03

http://scn.sap.com/community/abap/blog/2012/06/16/back-to-the-future–part-04

http://scn.sap.com/community/abap/blog/2012/08/06/back-to-the-future–part-05

http://scn.sap.com/community/abap/blog/2012/08/17/back-to-the-future–part-06

http://scn.sap.com/community/abap/blog/2012/08/31/back-to-the-future–part-06

Other OO blogs I have written:-

http://scn.sap.com/community/abap/blog/2012/09/08/design-by-contract-in-abap

http://scn.sap.com/community/abap/blog/2012/10/27/crossing-the-great-divide–procedural-vs-oo-abap-programming

http://scn.sap.com/community/abap/blog/2013/01/08/domain-specific-language-in-abap

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

http://scn.sap.com/community/abap/blog/2013/04/18/are-you-writing-evil-abap-code

http://scn.sap.com/community/abap/blog/2013/06/17/are-you-writing-dirty-filthy-abap-code

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

http://scn.sap.com/community/abap/blog/2013/10/03/abap-objects-is-the-way-forward–part-03

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

http://scn.sap.com/community/abap/blog/2013/11/17/dark-is-the-sun-bright-the-sky

Assigned Tags

      13 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Very nice blog. I look forward to the next part(s).

      • Create one or more Z tables, with key fields based on the fields that influence the decision, and then store the field order

      I did this in an earlier progject. The changes needed quite often don't fit the rules tables. so I end up with a complex program plus complex tables.

      Rob

      Author's profile photo Former Member
      Former Member

      Keep it going Paul. Had new insights while reading your blog.

      Author's profile photo Graham Robinson
      Graham Robinson

      Hi Paul,

      Great to hear you are coming back to Australia.

      I am very interested to see how you progress with this project.

      One related subject you didn't mention in your blog was the Enhancement Framework. I think you might find placing well thought out enhancement options in your code will allow you to achieve a lot of what you are after.

      For example, in your first scenario you could use the new BADI concept to both implement and manage the appropriate calling of the correct method for each country.

      I did a presentation at Mastering SAP Technologies and at SAP TechEd on this a few years back where I demonstrated this concept. The video of this is still available here.

      Cheers

      Graham Robbo

      Author's profile photo Thomas Jung
      Thomas Jung

      Even as I was reading your blog, I had the same thought that Graham Robinson did: Enhancement Framework and Filtered BADIs. Many people only think of BADIs and the Enhancement Framework as a way to enhance SAP standard.  However they can also be the perfect technology to add flexibility to your own custom applications.  After all this is the technology that has allowed SAP to merge multiple country and industry versions into one code base. 

      Author's profile photo Wolfgang Dörner
      Wolfgang Dörner

      Hey Paul!

      Nice blog - respect for your proactive behaviour!

      You asked for feedback- so here you are:

      First:

      Learn UML for modelling your architectures in ABAP OO. It is provided in several books (even used in 'SAP Books') and you can learn the basics for class-modelling in the internet. With UML your designs are easier to understand for the rest of the community than your actual sketch.

      Second (relating to example 1):

      Your idea of a dynamic superclass and subclasses for each country sounds good. But it is hard for me to understand the scenario, ypu described...

      Third (relating to example 2):

      Which ALV-Version do you use? Using the new SALV-Model, there is no need to create a fieldcatalog. You can just hide the columns you are not using with some simple lines of code. An alternative would be to program your structure dynamically. Dynamic programming is not trivial, but would be effective here. You can choos the fields of structure in runtime. If you want some background information you can look for "dynamic structure" on scn or google. Here a sample-link: http://wiki.sdn.sap.com/wiki/display/ABAP/Dynamic+Internal+table.

      As a young developer, who works together with some experienced ones, that are not familier with OO-Design-Techniques and so on, I really appreciate your will to learn the 'new things'.

      Cheers

      Wolfgang

      Author's profile photo Thomas Zloch
      Thomas Zloch

      Excellent effort. I will point people here that complain about having their copy/pastes and ten-liners rejected to show them what a 5 star contribution is.

      Also looking forward to the next parts.

      Cheersy Cheers 😉

      Thomas

      Author's profile photo Former Member
      Former Member

      What a great blog. It's fantastic when people dig into the guts of a subject and take us along with them. Particularly when most submissions seem to consist of, "there's this new concept and this is what the manual says about it", contributions like this one are so valuable.

      I agree that the enhancement framework is a major piece of new functionality that wasn't mentioned in this blog. However, it's always seemed to me that the enhancement framework does exactly what you're proposing: it's just a combination of the strategy pattern (which encapsulates different ways of doing something in a class) and the factory pattern (which in this case is used to instantiate different strategies, depending on the country required). Instinctively, I'm inclined to prefer the approach that uses the polymorphic capabilities of the language directly, instead of employing an orthogonal, but functionally identical, supra-language concept. However, the enhancement framework does provide a more explicit affordance to other developers by telling them clearly, "you can create new enhancement implementations here". If there's something I'm missing, maybe Graham can explain why he might choose the enhancement framework over your approach.

      With respect to your varying ALV output, your problem is not technical -- in such a way that it could be fixed by some runtime dynamism -- but rules-based: it is logically difficult to succinctly express the rules that determine how your table should look, whether with IF statements or a table of rules. When the problem domain is complex, there is no way to state it more simply in code. So the goal, I think you've decided, is to make your resulting code as maintainable and modular as possible. As Rob said above, shoehorning complex rules into a table can be counterproductive, but could be worthwhile if your rules change very often. If there is a lot of logic that depends on the structure of the ALV you will be creating, then splitting it into subclasses seems a solid idea: this is exactly what subtype polymorphism is for. If there is less logic, then you could probably improve things simply by decomposing the long routine into smaller methods in the same class, but perhaps you've decided that won't help. Finally, while BRFplus is good at dealing with complex rules, I fear that using a rules engine for a problem like this may just complicate things. You've got a new hammer, but I'm not sure that this is a nail.

      Really looking forward to your next installment.

      Author's profile photo Paul Hardy
      Paul Hardy
      Blog Post Author

      Thanks everybody for the feedback. I will do a combined response at the start of my next blog. I will say though that the ideas and thoughts that people are proposing are just the sort of thing I was looking for.

      Cheersy Cheers from the Moscow-St.Petersburg Train

      Paul

      Author's profile photo Paul Hardy
      Paul Hardy
      Blog Post Author

      Thanks everybody for the feedback. I will do a combined response at the start of my next blog. I will say though that the ideas and thoughts that people are proposing are just the sort of thing I was looking for.

      Cheersy Cheers from the Moscow-St.Petersburg Train

      Paul

      Author's profile photo Paul Hardy
      Paul Hardy
      Blog Post Author

      I just spent about two hours writing the next blog, and suddenly in the middle of me typing a sentence the site decided to publish the blog for no reason I could see. My cursor was nowhere near the "publish button". I didn;t want it posted 50% complete, so I had to delete it i.e. lose everything I had just written. This is why I prepare the whole thing on word first, as I heard a rumour this sort of thing happened on the new SCN. It makes me want to cry!

      However, at least it is not raining.

      Author's profile photo Phillip Manning
      Phillip Manning

      Hi Paul,

      The only thing I add to the above comments is that I would use a combination of Interfaces and Inheritance.

      For instance, you could have a ZIF_DELIVERY_PRINTER interface, which has the method PRINT_TICKET. Then you could still use the classes from the inheritance heirarchy when that made sense (The parent class would implement the interface, the subclasses would re-define the implementation). But you could also use a class from a completely seperate hierarchy if that made sense. You leave your options open.

      As for the field catalog problem - if you create a class that provides a service (again via an interface), then the rest of your program doesn't need to care about how exactly that information is stored - and more importantly the service consumer doesn't need to change if you decide to go from hard-coding to table-based storage or BRF+ within the service provider.

      Cheers,

      Phil

      Author's profile photo Kenneth Moore
      Kenneth Moore

      I actually have done a project similar to your 1st Example.  Works pretty good overall I think.  I have a main class (parent) and several children classes which inherit from the parent.  You can redefine the inherited methods.  You can add children specific methods. 

      One kind of gotcha I have ran into is that sometimes I find I may have a large parent method for which I would need to redefine some logic.  It may be just a few lines of code, so I don't want to rewrite the entire method.  I just need a "user-exit" for the child class.  So I end up putting a "dummy method" in the parent method.  The method has no code in it for the parent, but I can redefine it for the child classes.

      Another annoyance in reviewing code in a program using the inherited class, the class instance is determined at run-time.  So if I dble-click into a method while in the SE80, it will always go to the parent definition.  Makes sense, but if you don't understand that the class instance is dynamic, it can be challenging.  You have to be mindful, 'Oh, yea.  This method is redefined in the child class.  I need to look at the child class definition of the method.'

      Author's profile photo Pawan Kesari
      Pawan Kesari

      BADI framework is worth looking at, it resembles your example 1.

      You can read more about how to use BADI in blog http://scn.sap.com/people/thomas.weiss/blog/2006/04/03/how-to-define-a-new-badi-within-the-enhancement-framework--part-3-of-the-series

      In short, you will create a filter dependent BADI definition on LAND1 for example and define interface within BADI definition say ZIF_DELIVERY with method PROCESS_GI and call this method in your program. Implementation of this interface is then left to country specific development team. Once they implement the class from this interface BADI framework automatically calls the implementation based on filter value. There is concept of fallback class which you can defined and will be called when no other implementation is found.

      Obvious advantage I see is

      1. You use SAP standard method of code enhancement. No extra bit of coding for instantiation of classes.
      2. Existing framework will help defining BADI and maintain its implementation. You will see all implementation a one place well organised.

      Waiting for your next blog.

      Regards,

      Pawan.