ABAP 2 the Future – my version of the BOPF chapters
It rarely happens that I’m really looking forward to a release of a book. The announcement of “ABAP to the future” by Paul Hardy was such an occasion. Reading the TOC, I was 100% positive that Paul picked the right topics which were needed in order to fulfil the promises of the title.
Particularly I was excited about the BOPF chapter: I have given a couple of trainings, been to TechEd with the topic, promoted it to management as well as fellows and all the time, the same questions are being raised: “Why have I not heard about it before?”, “Is there an official training at SAP?” and “Is there a book about it?”. While I still can’t answer the first one, the answer to the second one is “yes, WDEBOF at least gives a rough overview”. I always answered “not yet” to the book-question and was excited to be able to answer it with “yes, and the title of the book is very appealing to management as well: “ABAP to the future” (A2tF, to find an abbreviation).
I finally started to read it and have to admit that I don’t agree to a lot I read. Sharing this opinion with fellows, I was encouraged to write my comments on SCN so that we can discuss them.
Preface: This is my opinion based upon my experience and architectural as well as programming style. @Paul: You have done a great job collecting and preparing those topics. Thanks for including BOPF in it. I hope you don’t mind my criticism and the style I chose. I would love to read your comments on my writing and discuss on the each and every aspect. Often, there’s no “right” solution, so I guess that other readers joining the discussion would also benefit from it.
Instead of picking all the small pieces which I would like to comment on, I chose to write a partially alternative version. This is of course more challenging and exposes my poor writing (I can’t keep up with Pauls entertainment for sure, I’m German), but I hope that third persons can understand it more easily. Still I will not repeat parts which I agree with. You’ll have to read the chapters yourself and create your own picture which suits your experience and architectural style. Anyway, it’s worth buying the book ;)
So here we go:
A BOPF model is a representation of a real-world object. With a very low representational gap, the model which is designed in a dedicated modeling environment in the ABAP backend (in fact, there are multiple designtimes based upon the same model, we’ll come to that later). This so-called “outside-in” approach doesn’t only make it easier to consume the model, but also to discuss as a developer with domain-experts with the same vocabulary. But be careful: The business object is agnostic to the consumer (e. g. doesn’t know anything about the UI). Deriving a model from a UI can render your model inflexible or in-appropriate for other consumers. Modeling a business object is very similar to modeling a UML class diagram: You think about how the things work and use your brain and methodology in order to derive classifiers (classes) and behavior (methods) – if you don’t have a methodology which helps you to decide what makes an entity, I highly recommend reading Craig Larman.
Before we head to the system, let’s make a plan. How does a monster look like? A monster is composed of many parts (UML: classes) which are interconnected (UML: by associations). Those which are connected with a dependency that the parts can’t exist without the monster itself (UML: composition associations) will form our monster business object. An analysis of our usecases has resulted in the monster itself needing a name and a creator. It has a head, it can even have multiple heads. About the legs and arms we might bit a bit uncertain: When is an arm an arm, what makes the difference to a leg? We might decide for an entity “extremity” instead. All these questions might not occur when deriving the monster from a UI. We might instead have come up with a model where we’ve got only one head (as an attribute of the monster) and six attributes leg1..6. Now let’s move to the modelling environment. I recommend to directly utilize the BOPF Expert tool (transaction BOBX) unless you’re got EhP7, SP8 and are happy to be able to utilize the BOPF in Eclipse plug-in. The BO Builder (BOB) is less powerful and should be used only when extending business objects.
Preface: About addressing model parts
All entities of a model are technically encoded as GUIDs. When programming with BOPF, we technically pass the GUID in order to address an aspect of a business object which we’re talking to. This is necessary, as the command pattern and the service layer pattern are fundamentals of the BOPF architecture (we’ll talk about this in more detail later). Just one word upfront: In the beginning it might feel a bit cumbersome, after but you get used to it very easily as the pattern is ubiquitous. In order to make the code more readable (and writable) for the human, BOPF generates a so-called constant-interface which has a human-readable constant containing the GUID. During debugging however, you are confronted with the GUIDs.
Hint: There are various ways in order to translate the GUID back to the model-entity. The easiest one is to press control+F in the BOPF designtime and paste the GUID. The UI will navigate to the corresponding model-entity (at least in the SAP-GUI-based tools). When debugging, you might not want to leave your debugging environment and can utilize the debugger script /BOBF/TOOL_DEBUGGER_SCRIPT.
The wizard guides you through the creation in BOB, you basically have to select proper names. If you started in BOBX, a root node with name “ROOT” will be created immediately. The so-called root node is the topmost entity upon which existence all other nodes depend on (as Paul wrote comparable to the top level of an XML document).
I recommend you not to choose any other name than ROOT, as the ROOT kind of represents the object itself. Naming it like the object (e. g. MONSTER) is redundant (as all node-names are unique only in the context of the BO) and giving it a name (e. g. HEADER) makes it more difficult to identify as top-level node. BOPF also creates associations for all lower level nodes to the top-level-node which are called “TO_ROOT”, so it would be nice in my opinion if TO_ROOT also found the ROOT node.
The structure of each node contains two major parts which are modeled for each node: One for the persistent structure and one for the transient structure. The persistent structure will be included into the database table which BOPF will generate for you. The Transient structure contains information which can be derived at runtime.
Figure 1 – The different structures and types modeled for each node
The combined structure is the one used at runtime (the one you code to). It includes the persistent structure as well as the transient structure (if transient attributes exist on the node).
Figure 2 – The root-node’s combined structure used at runtime
It’s a bit tricky to distinguish between transient attributes and UI-control-information. I recommend to include attributes into the transient structure which are relevant to the business (and don’t think about the UI). For a monster, it is necessary how many heads it’s got, as it can bite once with each head (assuming only one mouth per head). Thus, we should have an attribute “number of heads” on our ROOT node. However, this can be easily derived by counting the number of HEAD-instances for each monster. It doesn’t need to be persisted, but it could be also stored if updated after each head-creation or deletion. Whether an attribute is transient or persistent is transparent to the consumer, as both structures are included into the “combined node structure” which is being used for consumption. You can even move attributes between the two structures without disruption. Information which is solely necessary for the consumption by a human (via a user interface) like language-dependent texts to a coded value should never be part of the model, but should be added on an architectural layer closer to the UI (I call this layer upon which the UI-controller is based upon “service adaptation”, but this aspect is not part of this chapter). My recommendation: If you can derive an attribute but want to search (the database) for it or if the derivation is very expensive, include it in the persistent structure. Else, give the transient structure a try.
The names for the runtime structures will be proposed by some funky algorithm which resides in BOPF. I recommend to just keep the prefixes and suffixes as they are (and only change the semantical part if necessary), as it is very beneficial if the naming is the same within your development team. And there’s always a lazy team member which just goes for the proposal 😉
If you’ve got a deviating naming convention in your company, feel free to extend the BOPF code which does the proposal. Doing this will help you tremendously to learn how BOPF itself works – and might open your eyes a wide.
Figure 3 – Don’t waste time thinking about the technical names…
Figure 4 – The almighty name-proposal.
Enter the entity names (such as node names) and let BOPF propose the technical names
After you got the structure names proposed, use forward navigation to SE11 (by double-clicking on the structure names) in order to model the persistent and transient information.
Finally, generate the runtime artifacts from the “Extras”-menu:
Figure 5 – Result of the DDIC generation
Our monster shall be able to feature heads and extremities. As the heads depend on the existence of the monster itself, this will be a subnode to the ROOT node (in contrast to “FINGER” which depends on the existence of the node “EXTREMITY” and would be a subnode of the subnode, if we modeled it, which we don’t for the sake of simplicity). Also note that the node-name is in singular! How many heads a monster may have is a property of the association between ROOT and HEAD (its cardinality) and might even change as the system evolves (usually from one to many 😉 ). Also, we don’t prefix the node-name with the business object name itself, as the node is anyway context-dependent on the BO.
Figure 6 – The monster’s node structure.
The composition associations are “model elements of the root-node”.
As I wrote above, a BOPF Business Object comprises all the entities (as nodes) which are connected by compositions. As we create the subnode, BOPF implicitly also creates a composition association along with it. All associations in BOPF are directional. The composition, which usually has the same name as the target node leads from ROOT to HEAD. As all associations are directional, another association which leads from HEAD to ROOT is also created implicitly: it is called “TO_PARENT”. This association exists for all the subnodes of our model, just like “TO_ROOT” which always associates the ROOT node from the subnode. While TO_PARENT and TO_ROOT always have a cardinality of 1, the compositions’ cardinalities have to be modeled.
Note that – just like in the UML – nodes and associations are different entities of the metamodel. In the constant-interface, you can also experience this easily: There are separate constants for zif_monster=>sc_node-head and zif_monster=>sc_association-root-head. Also, there can be multiple associations between the same nodes: E. g. we can imagine one head being a preferred one (which takes most of the tasks). or a relationship between the monster (root) and the heads with hats.