Hi! I haven’t been on the SDN for a long time. In the meantime I changed job. In discussion on the Klaus Meffert’s weblog “SAP Developer Network: Design Patterns: Boondoggle or State-of-the-Art?”, I expressed my thrill about ABAP objects and design patterns and said that I have a wonderfull experience. Many people got interested in details, but up to now I hadn’t time to write a weblog on this. I still owe you the description of how I got to use objects and design patterns in ABAP succesfully. So, here I’ll give you the whole story.
Starting with objects and patterns:
Klaus’ experience sensed correctly that there was «something wrong» with my project. How could I start as an objects and patterns novice and end up with good results? Well, I’m neither a guru nor I’m inflating the success of this project. The project was simply setup loosely. I was asked to estimate some time frames, and was very scared because the project was bigger than the previous one, that I could hardly cope with in procedural programming. I knew that it would be completely impossible that way and I said so. I said that I could try with objects, although noone else knew what it was, except that I said that it was the only way. Since I am the only developer in the company, noone, including me, couldn’t predict the results (exactly as Klaus said). However, I was told explicitly that noone will raise hell if I exceed the self-setup terms. I didn’t want to think about complete failure. So I took a deep breath and started. I had a dimm picture of objects, I was using ABAP controls, had some experience with Visual Basic and VBA, but I knew clearly that what I did wasn’t really object programing. So I bought Design Patterns Explained (I chose it for being beginner-friendly) and read it while I was on vacation (on the beach and in parks while nursing my daughter) and got much clearer picture on objects paradigm as well as a few basic patterns. From the time I started till production, I exceeded the official project terms by double and noone complained, as they promissed. Especially because they were very satisfied with the result. Noone calculated costs neither. Even if they wanted to, it would be impossible since I was never asked to keep exact time-sheet, and I was working on many other projects and small daily tasks in parallel, switching daily on irregular basis. I wish I kept the time sheet for my own record and future estimation.
The project goal:
My ex-company is a retail one, and has it’s own net for distribution of advertising newsletters directly to people’s mailboxes. My application had to cover the entire process: dividing the country to cities, plants (stores) and subareas, recording the streets with housenumbers and number of households for each subarea, hiring distributors and inspectors, distributing the weekly newsletters of different types, managing clients’ complaints, inspecting distributors’ work, ordering external services (transportation, external distribution), payroll to inspectors and distributors Enough to cause a headache. Especially if done in procedural way.
General idea is simple:
So basically, I created a little Z* database and an application to maintain the tables all from one place. The application consists of a command tree to the left and editable table-maintaining ALV grids to the right (they open in docking containers which are automatically shrinked by the command tree). Besides standard ALV functions, they all have common toolbar with «refresh», «togle display/change», «save» and «close» commands. Each grid can also have specific commands such as «run payroll» or «send fax».
As generic as possible:
I tended to create as many generic reusable components and as little application specific code as possible. In the next few sections I’ll describe the generic components that I’ve created and how they interact.
Improved ALV grid:
So first I created an improved ALV grid. It has many simple but useful features (record-count display, last used disp. variant, toggle display/change ), but the most important one is capability of maintaining dict. table contents completely independantly (fetching and saving data), with basic fields check (duplicated keys, obligatory flds ).
Generic command tree and interface:
Generic command tree contains a column tree with nodes. Each node represents an object with generic interface, which can accept simple commands: open (in edit and display mode), get sub-nodes (and corresponding objects), get context menu, create, delete This interface was ment to be a generic basis for further development of other generic dictionary classes or application-specific ones. It can be including in any type of objects, with different implementation. I guess this is Adapter pattern, is it?
ALV grid tree component:
This class contains the above mentioned generic interface and adapts the improved ALV to be hung to the tree. Implements some handy fetures such as navigation from specific hotspot enabled fields (GL documents, vendor master data, assets ).
To avoid hardcoding for constant values in the program or increase development effort and confuse users with standard customizing tables, I have created a generic component for maintaining parameters values (stored in INDX table). One program can have one or many parameter objects (they have unique IDs), which can belong to program generally, or to particular objects.
For me, the most exciting generic component is the one that was implemented as a Decorator pattern. The generic abstract class was made to provide lookup data to the display structure. For example, if the main table contains field LIFNR (vendor number) and the display structure contains both LIFNR and read-only VENDOR_NAME, the latter field must be fetched from vendor master data and filled into the internal table. Decorators make it easy and reusable: they exist as separate classes the implementation of fetching VENDOR_NAME from vendor master data is implemented only once. The decorators are chained up in such way that a method call of the last one ensures chained method call of all others (they call each other respectively). For example, one decorator is «vendor master», the other could be «plant names» or such. Although usage is extremely simple and elegant, for detailed description it would take another weblog.
These are not all components, but only the most important ones. They are mostly abstract and can be used only if redefined locally. However, redefinitions are very simple and in many cases consist only of initialization in constructor.
My first ABAP-OO-Patterns project included creating these reusable components and that’s why it lasted so long. But further applications proved that it was worth it. They were piece of cake: it was only composing ready-made bricks which fitted smoothly, with a little application-specific coding.
However, this is not a completed work. So far I have only ALV grid table maintenance to hang to the tree. While it was enough for my applications so far, it’s obvious what’s missing the most: ALV grid is a good object replacement for non-object table-controls, but it would be nice to have a replacement for a standard dynpro with fields, tabstrips etc spread all over it. I have in mind two directions: something based on dynamical documents web-like control (fully OO), or a component which would handle standard dynpro as a sort of interface between object and non-object world (I’m more sceptic about this). Or both. Well, the system is open, and all sorts of plug-in components can be developed in the future. Ofcourse, if ABAP survives at all, since Klaus Meffert and many other people who forecast ABAP being overrun by Java, might be right. Even so, I find this experience very exciting and helpfull.