ABAP OO Design part 5: Step 2 Determine classes from actions
In the previous blog post the main class categories are explained. Now we are going to assign the actions to classes categories which should be responsible for the action.
The classes will all be specific classes, which means that the classes are specific to the solution. In the design step “Reuse optimization”, we will make the classes as generic as possible, so maximum reuse is achieved.
OO design concept: “The object takes care of itself.”
In OO design you cannot compare everything to the real world. Things that cannot do anything in the real world, can do things in the OO world. Let’s explain this by an example.
A Sales Order Business Object can not do anything in the real world. In the OO world it can. It can be commanded to do Update itself, Approve itself, create a Adobe document and add it to itself and so on.
Real world example
Normally I try to avoid real world comparisons but maybe this example makes it more clear.
For example a mother wants a child to put on a jacket. The mother could help the child to put on the jacket. For example in mother object is programmed:
DATA(jacket) = zclo_jacket=>create_instance( color = blue ). child->put_on_clothing( clothing = jacket ).
Design pattern example
In OO the child should take care of itself.
The mother instance commands the child to do it:
child->put_on_clothing( clothing_type = jacket ).
The child puts on the jacket by himself. How the child puts on his jacket is his own responsibility. He might get the jacket from the hatstand or he might have to buy it first or he can create he can command the jacket to create itself.
So in the child object in method PUT_ON_CLOTHING is executed:
DATA(jacket) = zclo_jacket=>create_instance( color = blue ). APPEND jacket TO clothing_list.
In the anti-pattern example the client class (the mother) has to create the jacket. In the design pattern example the client class does not have to create the jacket. So this is more loosely coupled and the Child object is less dependent on the Mother object.
Ok, so far the real world. Let’s get back to the OO world. So in the OO world a Business Object is like a robot. It is independent and can do stuff.
Examples in the OO world where an object takes care of itself:
- Sales Order BO creates itself.
- Sales Order BO updates itself.
- Sales Order BO creates and adds Adobe Document to itself.
- Adobe Document create itself based on ABAP data + Adobe Form to a PDF data.
- Email can send itself.
- and so on…
Designing is an iterative process
When you hesitate about assigning an action to the right class, than that’s not a problem. Designing is an iterative process of continues challenging the design decisions. Often it helps discussing the decisions with your peer developers. Spending extra time on design will save a lot of time during programming and testing.
Sales Orders, Customers, Materials and so on are Business objects. Supporting objects like Adobe document, File, Email and so on are not business objects. But how are they called? In the past I called them “Non business object”, but I do not like the name. So I decided to call them now “Supporting objects”. If you have a better name, than please send me a message.
To the explicit class categories like business object, data provider, model, view and so are given a stereotype name in the class diagram like <<business object>>, <<data provider>>, <<model>> and so on. For Supporting objects I won’t add a stereotype name.
In the examples below you will first see table with the actions linked to the suitable Class category and a rationale added in bold text.
Example: Send Sales Order document by Email to Customer
Creating an output message (NAST) during creation of the Sales Order.
This is customizing, therefor no custom ABAP needed for this action.
Create Print program which is needed for the Classic Output Message Framework (TNAPR/NAST).
The Classic Output Message Framework requires this to be an ABAP program with a FORM routine.
Read Sales Order Document Data.
Data is always read in a Data provider class.
Create Sales Order Form
Adobe Forms are created in transaction SFP.
|Is not a class|
Create Sales Order Adobe Document
The object supports the Sales Order Business Object. It is a aggregation (“has-a”) child of the Sales Order Business Object.
Create and Send Email
The object supports the Sales Order Business Object. It is a aggregation child of the Sales Order Business Object.
Business Object Sales Order
This is the business object which is responsible for all the actions.
Example: Create Starter Pack Sales Order by Incoming interface
Receive Starter Pack Sales Order data from Fiori.
A class receiving data from an client is called a Service class. This name is based on names like OData service and Web service.
Determine Starter Pack Material.
The responsibility of knowing which material the Starter Pack Material is, is assigned to the Starter Pack Sales Order Business Object. It could be in future that the client will send it to the service.
A Customer creates itself based on the data it gets. Customer is a Business object.
Create Starter Pack Sales Order.
A Starter Pack Sales Order creates itself. It is a Business object.
Add Contract PDF file to the Sales Order.
The PDF file is an object. It is not a Business object, so it is a Supporting object.
Example: Add a Christmas Present material to Sales Orders by Batch program
Batch program with selection screen with test run parameter.
A batch program is built in the presentation layer. So it must be based on APP, MDL, VW and CTL.
|APP and MVC-classes|
Select Sales Orders
Reading data is always a responsibility of the data provider. In this case it returns a list, so it is a List data provider.
|List data provider|
Add Christmas Bonus material to Sales Order.
This is the responsibility of the Sales Order.
|Sales Order Business Object.|
Send notification email to customer.
This one has two objects. The email and the customer.
Customer -> Business object
Email -> Supporting object
Write log to ABAP list.
Displaying to the user and getting input from the user is a responsibility of a View. The log is a Supporting class.
Log -> Supporting object
Log screen -> View class
Write errors to Application log.
Application log is a supporting log. It is the generic log accessible by transaction SLG1.