Designing for ABAP OOP and coding against interfaces with text-based diagraming tool.
As ABAP developer creating custom code (less than 10KLOC) for various user stories, when I started with object-oriented programming (OOP) in SAP, I had to start to solve below design problems:
- what the design should contain,
- how much design I will do up front,
- how I will display it in graphical way (I prefer graphical way to see to design of my software solution) to see bigger picture,
- what diagramming tool I will use,
- what kind of diagram I will use,
- how I will backup versions of the design,
- how to create the diagram so that I would reuse it in coding,
- how to ensure that other developers could update the diagram without a software with some proprietary license (so I was searching for open source software)
My approach to the solution.
In old technical docs from my team I saw there flowcharts in visio format (I did not have a software to update visio), or flowcharts/diagrams created in Word, or Excel- creating diagrams in Word/Excel is not comfortable for me, it is slow, cumbersome, placing of arrows and boxes takes time. Although I did not try many graphical proprietary diagramming tools, I assume that the cumbersome playing with arrows and boxes would be very similar.
I started to search what kind of diagram I will use. I decided for UML sequence diagram and class diagram.
Then I searched for the tool and l discovered that there exist tools where it is possible draw diagrams with text input. Like PlantUML.
The language of PlantUML was easy to learn. UML diagrams in PlantUML are easy to create and their txt files can be easily stored on Github. It has various licenses to select from, it is open sourced. The ABAP code in our team is confidential so I downloaded PlantUML to my computer, so I do not use web online server to create diagrams. For me, now, drawing the diagram with text input is much better than using some graphical tool, with drag and drop arrows, boxes…
When I had this new tool then in my first next project, I started to use it. My plan was that I will create my diagrams at the end. I proceeded as follows — I spent quite a lot of time up front (several days) with designing in my head (only in my head ) what I will code (design), then I started coding ( adjusting the design during coding, based on new knowledge) and after I finished the coding I created the class and sequence PlantUML diagrams. This approach had disadvantages that I spent too much time (more than I would like) with up front design (I was trying to keep too many things in my head, I was not able to keep all things I wanted in my head only…I invented something and then forgot it), I was not able well to think well about the names of interfaces, data types, how their signature will looks like exactly. I was missing the graphical way to see my design before I start to code.
In next project I started to code sooner and to think about smaller part of the design. This had advantage for me that I did not have a big headache from thinking too much before coding and I had impression that I am doing something, not only thinking about the design. But it also caused that I had to change more often names of interfaces, classes, methods- because I did not think it over before coding well, design was suffering, and renaming (although I use Eclipse and test driven development – so I can run regression unit tests in seconds) took more time then I would like (especially if the object is in revtrac, then I needed to delete it from revtrac….creating objects without adding them to revtrac would mean that later I would need to do it separately…) . Also, I was still missing to see bigger picture of my design. I created again the class and sequence PlantUML diagrams only after coding.
I realized that I need to start to use PlantUML diagram before I start to code, so that I could better think about the design and to see bigger picture. But I did not want to create diagrams which would take me too much time and I would not reuse them in the code and I needed a way how to force myself to keep them updated during the coding because they would not be in sync with the code at the end of the project. I realized that what I really need in diagram so that it is reusable in the code are interface names, method names in interfaces, parameter names, data type names, class names, exception names. All these names need to be real names which I will use in the code, no useless details, and diagram should be sequence diagram where I need to see how interfaces are calling one another. I started to look at my code from interfaces point of view.
In my next project I proceeded in this way and I now I am still doing it in this in this way.
It is easy to change names in the PlantUML diagram, add new interfaces…just an update in text file. Much easier than if I do it in real ABAP code, with real ABAP objects. I have discovered that when I create the diagram, then in fact I am already coding. I can go deeply in the design without coding in ABAP and try/explore different designs (and backup these versions to Github, if needed). Now when I spend few days working only on the diagram, then I do not have bad feeling that I am designing too much up front. So, the creation of this kind of diagram for me means the coding and designing at the same time, almost without any waste. For me it is coding against interfaces, exactly on abstract level what I need for my OOP. It complements very well my test-driven development (TDD) because the interfaces are dependencies in my classes which I isolate to a mock (mocks are inevitable for TDD and can be created from global interfaces only). I have discussed this my TDD approach in my previous blog.
These advantages force me to keep the diagram always up to date, when I discover during the coding that I need to change or extend the design then first I go to the diagram, redesign it there (I can see how the new change fits to the whole picture/design), update there and then I go back to the code, copying names from diagrams to the code. Below is example of such a diagram and interface names. Most of the text in the diagram can be directly copied to the code. There is a very little waste (text not reusable) in the diagram and this is making the diagram powerful way to show the design without annoying/disturbing details and I can purely concentrate on the design, knowing that I will reuse the text I type there. I create only as much documentation as needed, not useless documentation.
How much up-front design and how many design iterations will be done using this diagraming technique is up to the developer. In one txt file can be more diagrams. So, if the diagram starts to be bigger, then it can be divided to more diagrams.
I include text part of PlantUML diagram in the technical documentation with the diagram picture so that the diagram could be updated later, for next story, in future.
There is another advantage of this approach (diagram with interfaces before coding in SAP) – it is possible to start the cooperation of several programmers – they can work each on separate classes which implement separate interfaces. This kind of cooperation is almost impossible when one procedural monolith code should be created which would handle a lot of unrelated tasks, not separated to independent interfaces.
Before I started with PlantUML I was analyzing if I need to create sequence diagrams after I finish the code or before. I discovered that I need them only before the coding, not after. This is the reason why I stopped to analyze ABAP programs which are doing sequence diagrams from existing ABAP code, it means after the coding.
Concerning class diagrams, I have found out that I need them only if I create more complicated structure of classes (like abstract class with subclasses), so that I could see structure relation between classes. In this case, I create class diagram before I start to code, in same way as sequence diagram. Mostly I prepare only sequence diagrams.
Concerning the class diagram of an individual class- my current opinion here is that if I design small classes, single purpose, in sync with OOP principles then class diagram of individual class is not needed. If I look to the definition of the class then I see what objects/methods are declared in public, protected, private section, and for this I do not need class diagram. In the class definition I see what I need, so I do not need to pull this info to UML class diagram. Also, SAP system (I am in release 7.4) has the possibility to create class diagrams from classes in SAP, in transaction se24. The class diagram generated by SAP is showing what interfaces are called by the class and this could be useful to become familiar with the new class, if it is bigger.
To summarize the rules, I have for this diagraming technique (for sequence diagram):
- I create it before coding and then I do as many design iterations as I need.
- I put in the diagram only interface names, method names in interfaces, parameter names, data type names, class names, exception names.
- I do not put there a text which could not be reused in the ABAP code (with copy paste).
- When during the coding I discover that I need to update or enlarge the diagram then I will do it first and then I copy the new name to the ABAP code. I am motivated to do it since it is easy in text diagramming tool, I need to look at the new change in the diagram- how it fits to the other parts of the design, I will reuse the update and at the end of coding I have a nice up to date diagram which I can use immediately to the documentation. I am using also TDD so after I finish the code, I have also unit test results ready (in the form of automatic unit tests in SAP unit test framework) and I do very little manual unit testing.
This blog shows technique used for smaller projects, not for large complex projects where a software architect should be involved.
Now I am quite satisfied with this style of work, this is the reason why I write this blog, but if somebody knows better way how I could solve all my problems above, I will certainly be glad to know about it, to analyze other option. This is a ready solution for the problems, listed at the top, which will encounter everybody who will start with ABAP OOP.
Can be displayed online in https://liveuml.com , for example, by copy/paste below diagram text.
skinparam participantbackgroundColor white
‘ hide footbox
participant “ZCL_NOTIFIERCONTROLLER” as p1
participant “ZCL_NOTIFIERBUILDER” as p2 << (I,#ADD1B2) ZIF_NOTIFIERBUILDER>>
participant “ZCL_SENDMAIL” as p3 << (I,#ADD1B2) ZIF_SENDMAIL>>
participant “ZCL_NOTIFIERLOG” as p4 << (I,#ADD1B2) ZIF_NOTIFIERLOG>>
p1 -> p2 : build_and_send_notifiers(
note over p2 #white
im_notifiertype type ZIF_NOTIFIERBUILDER=>ty_notifiertype
im_notifiers type ZIF_NOTIFIERBUILDER=>tty_notifierinput )
note over p2
TYPE: ty_notifiertype type c length 10
note over p2
BEGIN OF ty_notifierinput:
bukrs type bukrs
invnr type invnr_anla
txt50 type txa50_anlt
sernr type am_sernr
pernr type pernr_d
END OF ty_notifierinput,
TYPE tty_notifierinput TYPE STANDARD TABLE OF ty_notifierinput
note over p2 #red
p2 -> p3 : send_mail(
note over p3 #white
im_email type ZIF_SENDMAIL=>ty_email )
note over p3
BEGIN OF ty_email:
im_sender_email type ad_smtpadr
im_receivers type standard table of somlreci1
im_mail_text type soli_tab
im_mail_subject type so_obj_des
END OF ty_email
note over p3 #red
p2 -> p4 : log_message(
note over p4 #white
im_message type ZIF_NOTIFIERLOG=>ty_message )
note over p4
TYPE : ty_message type c length 200
p3 -> p4 : log_message(
note over p4 #white
im_message type ZIF_NOTIFIERLOG=>ty_message )
p1 -> p4 : get_log(
note over p4 #white
ex_log type ZIF_NOTIFIERLOG=>tty_message_log
note over p4
BEGIN OF ty_message_log:
message type ty_message
END OF message_log,
TYPE tty_message_log TYPE STANDARD TABLE OF ty_message_log