Charlie Visits the ABAP Chocolate Object Factory
Here is the Horror Film of the Year: Clash of the Design Pattern Titans – Evil Visitor Pattern vs Fearsome Factory Pattern from Hell. In ABAP Technicolour with OO surround sound.
Knights of the Round Table of Contents
- The Creation Myth
- Can you see a Pattern Forming?
- A Visit from the Spice Girls
- The “Helen of Troy” Principle
- Who’s that Girl Just Walked in the Fridge?
- The Mighty Thor, Son of Coding
- Enter the Bionic Visitor, with Factory Jet Pack
- Tales of the River Bank
- The Creation Myth: The Paradox of CREATE OBJECT
Hopefully by this stage I have convinced everybody that it is – at the very minimum – worth taking a look at OO programming? What’s that? I haven’t. Oh well, let’s presume I have, other the next sentence is not going to be of much interest.
Object orientated programs would not be much good without objects, so you need instances of objects, and that means CREATE OBJECT statements does it not? Yet it has been said that as soon as you code a CREATE OBJECT statement you are sunk, as you have nominated a specific type of class, and this is not very future proof as at some point in the future you may well need a subtly different type of class, and you are not supposed to change existing code and so you have painted yourself into a corner and so there is no hope in life and so you might as well go jump off the nearest cliff.
ABAP Programmers dropping to their deaths like a swarm of lemmings from great heights! This is bad in so many ways, and sunbathers on the beach below the cliff don’t think much of this situation either.
So how can you get around this problem, thus not only creating the right type of object every time but also avoiding sunbathers squashed flat like pancakes?
- Background Noise: Pattern Recognition
Recently I have been doing a technical review for a USA book designed to try and convince procedural ABAP programmers to move to an object orientated way of coding,
SCN (or whatever it is called nowadays) has very strict rules about talking about specific books, so I won’t go into detail, I will say the structure of the book is very sound – it starts with the basics of OO programming and ends up talking about various “design patterns”. I write about the latter all the time in my blogs.
This has filled me with a burning desire to do not just one but three blogs – one about the “state” pattern (again), one about design by contract (again), and this one, which is all about the factory pattern.
Whilst going through the various patterns in the book under review the same concept kept coming up again and again – if you want to be future proof instead of directly using a CREATE OBJECT statement the idea is to use a “factory” to get you an instance of an object. That way when things change – as they always do – you do not have to change the calling program(s), just the factory.
That is Conditionally Illogical, Captain
In most of the examples I see – and indeed in programs I have written myself, you always end up with some sort of conditional logic to decide the exact type of class to use, as in the following example:-
Figure 001: Machine Factory
This is fine and normal – but naturally when you have a new make of machine, you need to change the factory class. That is not the end of the world, surely? Well I am never happy so if I want to be really anal about the “open/closed” principle whereby you never change production code if you can help it, I need another mechanism here. The obvious answer is a configuration table, or maybe a BRF+ rule of some sort – the problem is that the logic needed to choose the exact class is never the same twice. A standard configuration table would struggle with this – and you would end up with dozens of the things, and even BRF+ might find itself in difficulty.
Even if the logic was dead simple – country code specific say – it would still be two changes – creating the new class, and updating the configuration table, and the effort of changing the code in the factory class or putting a new entry in the table would be about the same.
- Tell me what you want, what you really really want
Well, I’ll tell you what I want, what I really really want. It goes as follows:-
- A sort of “publish and subscribe” mechanism where a class describes itself in some way, and then a factory can read this “meta data” to choose the correct class.
- The logic for choosing the correct class can be as complicated as it wants, and different every time. A filter BADI is somewhat similar but I want the possibility of ludicrously complicated logic.
- This needs to work for both local and global classes.
Right at the start of this blog there was an allusion to the “Visitor” which is going to be fighting with the “Factory”. Here is a link to some Visitor based blogs:-
This blog is in effect a sequel to that series of blogs, so it would be best to read that series first – otherwise the examples later on will not make much sense without knowledge of the example “Visitor” program.
The problem was the Visitor pattern as traditionally described is that when you create a new class to be “visited” (a new type of monster making machine in my example) you have to change the visitor interface in question and thus all the existing classes that currently implement that interface.
That is a big drawback, not a very good match for the “open/closed” principle, and thus the advice is “do not use this (visitor) pattern when the classes to be visited keep changing”.
In the visitor pattern you start with a set of things to be visited – buildings in the book I was reviewing – and a set of things that want to visit them – different types of inspectors in the book. You have to make a guess that there will only rarely be a new type of building; otherwise the effort to change all the code is huge. I would say that due to Sod’s Law the instant you decide this is a good pattern to use because we never get new types of buildings, there will be a queue of new types of buildings banging on your door, that queue stretching from Lands’ End to John O’Groats.
Naturally I did not like the idea of having to change so much each time a new type of building (or monster making machine in my example) came along, so in the above blog I changed the design such that the only things I had to do was create the new subclass (monster making machine subclass), and change the factory class. Naturally I also had to add a new unit test, but I consider that a Good Thing.
So the next question is – can I take this one step further and only create the new class, and the Factory class magically knows about the new class I have just created and returns an instance of it in the correct circumstances? That does sound like black magic.
- Please Compose Yourself : The Helen of Troy Principle
One of the recommendations for OO programming is “favour composition over inheritance” i.e. in most cases it is better to have classes implementing interfaces rather than directly inheriting from a superclass.
This is a really bizarre concept to get your head around initially, but I have become convinced. I pretty much always start with an interface now and then create a ZCL class which implements that interface.
The unbearable urge to define the outside appearance of a class is sometimes called “The Helen of Troy Principle” as in “The Interface that Launched a Thousand Classes”. At this point I should really put in a hyperlink to Wikipedia to reference one of the thousand scholarly articles that reference this principle, but that would be difficult as I just made it up off the top of my head.
The Japanese say we have three faces – one to show to the world, one to your close friends, and one only to yourself. This is 100% replicated in OO class design via the public / protected / public nature of the various methods and attributes within a class.
Staying with the analogy of human nature it could be said that there is more than one face you show to the world – you might very well appear and act very differently at the office where you work as an accountant than down the pub with your mates during the beer drinking contest, and differently yet again during the several times a year where you take “sick leave” and are really on a secret mission for the government to recover the stolen atom bomb plans from an international master criminal on his secret island in the Pacific
This is where interfaces come in. At work the company you work for (client or calling program) only knows you via your ZIF_ACCOUNTANT interface. The caller knows you can do accountancy type things, and does not care about any other interfaces you implement, and naturally nothing about your protected or private attributes. You do not want to go waving your private attributes all over the place – you would get arrested. So the caller does not know your exact concrete class type, only that you are TYPE REF TO ZIF_ACCOUNTANT.
In the same way the calling program that is a shadowy government agency only knows you as TYPE REF TO ZIF_SECRET_AGENT and only cares that you have public methods enabling you fight men with metal teeth on top of cable cars, or drive your motorbike down a seemingly never ending set of stairs in an old European town, writing off countless pursuing police cars on the way and ending by driving through the plate glass window of the shop opposite the base of the stairway.
So when the dubious government agency wants a new agent for a mission it gets a new agent for the secret agent “factory” needing an instance of a class that (a) implements that interface and preferably (b) has the right sort of experience for the mission at hand i.e. an agent class designed for fighting men with metal ears on top of the cable car is sub-optimal.
Building a Better Chocolate Factory
In my current “Visitor” design I have several monster machine classes all implementing the ZIF_MONSTER_MACHINE interface and a local factory class which uses hard coding to create a specific type of class based on the make of the monster machine. Can I make a better Factory Class, a generic re-usable one?
Now before I go all free energy crazy and try and create a brilliant solution for a problem, the obvious question is – am I re-inventing the wheel? I have a quick look for standard SAP interfaces which seem to be doing what I intend and I find loads of candidates. However since there is no logical naming convention and nothing is documented I come to the horrible conclusion what I am looking for might already be there, but is impossible to find.
So I will build a solution myself, just for fun, and if one day someone tells me there is a better one right there in front of me, oh well, I will start using that instead.
- Who is that in the Fridge?
As I may have mentioned one of my favourite ever adverts here in Australia was for “Tap King” which was a beer dispensing device. In the advert a man goes to the fridge to get a beer, and who should be inside the fridge but (the real) Lionel Richie, playing the piano, and handing out beer.
I often have beer or wine in my fridge, but have to this day never found a pop star inside the fridge who would sing and hand the beer to me. Possibly I have the wrong make of fridge.
At this point a small number of you may be wondering how this (Lionel Richie / Beer) is relevant to talk of interfaces. Well, the starting point of designing an interface is getting a picture in your head of the abstract behaviour that you want – there is no need at this point to worry about how that functionality is going to be implemented as that is a separate exercise.
In this case I want a class to be able to “publish” the fact it can be used in an object factory, by implementing this new interface, and have a method where some dynamic parameters are passed in and some simple or complicated logic is performed giving a yes/no answer. All classes implementing the target interface e.g. the monster making machine interface are asked “given the current situation, are you the correct class to handle the job?” just like the secret agents above.
In other words the candidate classes have to be able to say “Hello” and be able to tell the calling class the answer to “is it me you’re looking for?”
- Coding Time : Face Off
The time for theory is over. Now is the time to get coding!
You can nest interfaces, so let us create a new interface which the monster making machine interface will contain, as well as any further interfaces I create in the future which I want to use my fancy new object creating factory technique.
You might expect me to give the interface and the method silly names, but much as I might be tempted to do just that e.g. ZIF_HELLO with method IS_IT_ME_YOUR_LOOKING_FOR I have to agree with Robert Martin and his rule “do not be cute”. Stupid jokes get in the way of one of primary goals which is to make the code read as much like plain English as possible. The names have to make it obvious what the purpose of the interface / method is. You could not tell what the use of interface ZIF_HELLO was from its technical name.
Moreover, above I just sort of slagged standard SAP interfaces off for having names where you cannot guess the purpose , so it would be “Dear Kettle, Love Pot” if I did the same myself.
A good standard SAP interface name is IF_SERIALIZABLE_OBJECT. If I see that in the list of interfaces in a class I know that instances of this class should to be able to stored in the form of an XML or JSON representation of their data. That is descriptive metadata just like you are supposed to attach to your “entities” in Gateway services.
Moreover if you see two interfaces which do totally disparate things – like “live inside blast furnace” and “sculpt ice cubes” then it is a clue there is something wrong with the class design.
Going back to non-silly names for the new interface: how about ZIF_CREATED_VIA_FACTORY? I considered ZIF_FACTORY_FRIENDLY but that was still too much of a joke. Even if I did not add any method definition to such an interface, having that interface in the definition of a class would still send a signal to any developers thinking about using that class that a factory pattern is the way to go. You can of course enforce that via the “create private” setting, here I am trying to say that you should be using a particular sort of factory pattern in ABAP, one for which there is no name yet as I am just making the thing up.
I have decided to call this an “OCP Factory” where OCP stands for the “Open Closed Principle”. The logic behind that is that the creation of the new class requires zero changes to any other class.
I give the interface one method, which takes in an arbitrary table of parameters and their values, and returns a Boolean result saying whether this is the class for the job (see screen shot below).
Figure 002 : OCP Factory Interface
I want the calling code to read something like:-
IF (CANDIDATE)=>IS_THE_RIGHT_CLASS_GIVEN( LABORATORY_SETTINGS )
The settings could be the make of the machine and possibly a whole string of different factors. Usually there is only one factor, as having different subclasses for various different factors causes “class explosion” and so is a bad design – but you want the flexibility to cater for exceptions that prove the rule. Just because I cannot think of any off the top of my head does not mean there will never be any.
Interface of Beau
Now the new interface is created, it is time to embed it within interface ZIF_MONSTER_MACHINE. That will of course cause all my existing monster making machine classes to have syntax errors, until such time I add in an implementation for the new method. When I change them the system warns me I need to make an adjustment to the class, and how right it is.
In each machine class I add the “complex” logic to determine if the machine is the concrete required given the incoming data.
Figure 003 : Logic within each machine class
This looks like a lot more lines of code required than in the original CASE statement in the factory class, but bear in mind we are trying to stop the factory class from needing to ever be modified again, and in any event huge blocks of conditional logic are something we try to move away from, for readability (and hence maintainability) reasons.
I have three monster making machine classes, I quickly change all three. All good thus far, time to create a generic factory class.
I think functional methods are great, but in some situations where I foresee lots of different object types being passed in, I use a CHANGING parameter when really I want to create a new object and return that object reference.
I do this because a returning parameters has to be a concrete type, but a changing parameter can be generic and I can use RTTI to get the specific type of class being passed in. You can see this technique employed in the “dependency injector” framework as described in the below blog:-
As a first step, my OCP Factory class has two methods – a public one to take in the context data and return a concrete instance of the correct class, and a private one to get a list of the Z classes which implement the interface of the object reference passed in via the CHANGING parameter.
Figure 004: OCP Factory Methods
The changing parameter is going to be of TYPE REF TO ZIF_SOMETHING in the calling program, but needs to be typed as ANY in the method being called. I tried to type it as TYPE REF TO OBJECT but the syntax check had a hissy fit. There are ten million billion standard ABAP table types for a name/value pair, I picked the Web Dynpro one, just be contrary, given I spend so much time slagging off Web Dynpro.
Figure 005: Parameters for primary OCP Factory Method
Just the Factory Ma’am
The first thing to be done is to get the exact interface of the CHANGING parameter being passed in, and make sure that parameter actually has been passed in as TYPE REF TO ZIF….
Figure 006: Run Time Type Identification
What is that “DBC” check at the end I hear you ask? That is in regard to the “design by contract” programming paradigm, as described in the below blog:-
Here I just want to be 100% sure an interface has been passed in as opposed to a concrete class type. The latter would ruin the next bit, which is to get a list of concrete classes which implement the interface passed in.
list_of_implementing_classes( CONV #( interface_passed_in ) ).
There is a private method in the OCP factory which just calls standard SAP function module SEO_INTERFACE_IMPLEM_GET_ALL to get a list of all Z classes which implement the interface of interest.
Naturally the factory method has no way of knowing the type of these classes so we have to stand by for a dynamic method call. We know the class name, and the method name we want, but there are also parameters to be sent and received – namely the context data and whether the class being queried feels it is up to the task at hand.
Another way of looking at this is as if we had an interface called ZIF_MENSWEAR_ASSISTANT and we were asking concrete class ZCL_MR_HUMPHRIES if it could help us and the response is “I’M FREE!”
Ever since OO programming has introduced to the ABAP language many years ago it has not been too difficult to build up a dynamic parameter table. The recent improvements in the ABAP language have made this easier still. In the code below we add the IMPORTING and RETURNING parameters to a table to be passed into the dynamic method call. See below for the code to build up the data needed to pass into the forthcoming dynamic method call.
Figure 007: Dynamic Parameter Table
In so called “Reality” TV shows like “The X Factor” the way the top three are announced each week involves giant pauses and dramatic music between each sentence, and in countries like the US and Australia an advert break between each word the host speaks as in “And (pause) in (pause) third (advert break) place ( pause) is (advert break) (huge pause) Joe Bloggs!”. Usually by this age half the audience have died of old age, despite being teenagers at the start of the sentence.
You might be feeling the same way about the long promised dynamic method call, but without further ado, no dramatic music, no advert breaks, here it comes!
Figure 008: Dynamic Method Call in a Loop
For each candidate class we dynamically call the method to ask if the class feels it is the class type we desire to be created. If so, all good, the CHANGING parameter (which is a RETURNING parameter) really gets filled with the correct concrete class type and we are done.
If by any chance an interface has been passed in which does not implement the ZIF_CREATED_VIA_OCP_FACTORY interface then an “illegal method” exception will be raised which needs to be dealt with. In dynamic program you need to do tons of error handling, more error handling in fact than that done by Jock McError Handling, the error handling Scotsman, winner of the “All Scotland Error Handling” contest 2016.
- London Calling
That is the OCP object factory finished, so now is the time to update my “Visitor” program to call the new Z class rather than the local factory class it had been using previously.
As always, every time I make the slightest change I execute the unit tests to make sure all that tinkering with the “under the hood:” mechanics has not changed the functionality.
Below is the changed code in the calling program – note that variable MONSTER_MACHINE is defined as TYPE REF TO ZIF_MONSTER_MACHINE.
Figure 009: Calling the Factory Method
I would have to add error handling in case the factory did not return a result, but the unit tests run so I have not broken the existing functionality.
I am very happy Easter Bunny with this, as in my previous Visitor design the monster machine factory was tightly bound to the calling class, which did not make the factory class re-usable in the least. Moreover judged by lines of code, the test class is now 60% of the Visitor example program. That may sound crazy, but I consider that a Good Thing. Stability is King as far as I am concerned. It is Good to be The King.
OK, you might say at this point, that was a lot of effort – why did we bother? In other words….
What have you got at the end of the day?
What have you got to take away? A bottle of whiskey, a new set of lies, a maintainability bonus that might take you by surprise.
As mentioned earlier in the classic “Visitor” pattern when you add a new type of object to be visited (e.g. a new type of monster machine) you have to change the visitor interface and hence tons of classes. I had whittled that down to just having to create a new class and also the factory class.
Now, as a test I will create a new type of monster machine class, this time called ZCL_FLORENCE_MACHINE, and see if I need to change anything in the calling program apart from a new unit test. Remember the unit test code does not even compile in production, so adding a unit test cannot possibly destabilise existing production code. So just to be 100% clear the idea is to create a new class, not change any production code at all and yet still have the new class used where appropriate.
I copy an existing monster machine class to my new “Florence” class, and make some trivial changes just so it returns different values from the existing classes i.e. so I can be sure that the new class is actually being called. Then I add a new unit test to the calling program. I re-run the unit tests, everything passes, oooo oooo, Mr, Peevly, Mr. Peevly, can I have a promotion?
Figure 010: Hair Bear Bunch
So don’t yell “Help! Help! Here come the bears”, don’t yell “Help! Help! Here come the bears”, don’t yell “Help! Help! Here come the bears”, let’s use a new improved factory class instead and then let’s split!
- Summary Mia, Here I Go Again
In this blog we have seen a mechanism whereby a new class can be created, and used in a factory class, without changing either the factory class or the program that calls that factory class, thus conforming to the “Open Closed” principle.
As soon as I build something I instantly start to think of gaps and ways to improve the “whatever it is I have just built”. This is rather like the UK children’s show called “Tales of the River Bank” where after the hamster and his mates had their adventure, the narrator would allude to another adventure and then say “but that is a story for another day…”
Perhaps a more accurate, if somewhat gruesome analogy is that in horror films the monster won’t stay dead, but thrusts a hand out of the grave in the last second of the film (movie). This started with “Carrie” and to be honest I was expecting it in “Batman vs Superman”.
In the case the monsters that constantly rise from the grave (or fall from the sky like in “Sharknado”) are either business requirements or technical requirements. Both are nightmares that have to be dealt with.
In this case I have some problems I want to deal with in a sequel to this blog, namely:-
- How to apply the same principal when the classes that implement the interface are local, not Z classes, and indeed the interface might be local as well. What if some are Z and some are local?
- What if you need more the one class coming back from a factory, as in my radically redesigned Visitor pattern?
Figure 011: Requirements seemingly satisfied come back for more
These problems will be solved – but that is a blog for another day.