In this chapter, we start with recipes for ABAP objects. This chapter is designed to provide useful recipes related to the storage of ABAP objects in shared memory and the database (persistent objects), as well as some useful design patterns. In this chapter, we will look at ways of:
Creating a shared memory object
Creating a persistent object
Creating classes based on factory methods
Creating classes based on singleton design pattern
Creating classes based on adapter pattern
This chapter explores recipes related to ABAP objects. Two useful features of the object-oriented ABAP are storage options in the shared memory as shared objects, and in the database as objects of persistent classes. The details about both the prerequisites as well as the necessary steps needed to created shared memory-enabled objects and persistent objects will be discussed later in this chapter.
Moreover, design patterns are very important in object-oriented programming. In this chapter, we will see how to implement three of them using ABAP objects, namely the adapter,
singleton, and the factory design. We will create a class with a
factory method design. Later, we will show how this class may be modified in order to behave like a singleton class. Finally, we will see how an object of one class may be converted to that of another using an adapter class. The examples are kept simple in order to emphasize on the design pattern concept.
For this chapter, we assume that the reader has basic knowledge of the ABAP objects, and is familiar with the class-builder transaction.
This recipe shows how to store the instances of your classes in the shared memory of the application server. A number of programs may access these objects that reside on the application server shared memory.
Two classes are necessary for shared memory, namely the
area class and the
area root class. The
root class is necessary for storing (encapsulating) the data that are to be stored in the shared memory. An
area class may comprise of various instances that may consist of a number of versions.
An important concept shown in this recipe is the
CREATE OBJECT statement with the addition
AREA HANDLE. This will create the object in the application server that is shared memory pointed to by the area handle
Prior to writing the code for storing objects in shared memory, an
area root class must be created and a shared memory area be defined using transaction
SE24; enter a suitable name to your
rootclass, as shown in the following screenshot. On the Properties tab, we need to make sure that the
Shared-Memorycheckbox is switched on.
We have named it
ZCL_MY_ROOT. We will then define two Instance Attributes, NUMBER and NAME, having private visibility, as shown in the following screenshot:
Two suitable methods, SET_DATA and GET_DATA, are also added to the class. The SET_DATA method contains code that imports number and name and assigns to the attributes NUMBER and NAME of the class. The GET_DATA method does just the opposite, that is, it exports the NUMBER and NAME attribute for a given shared memory object.
Next, the shared memory area should be created. This is done via transaction
Enter a suitable name and click on the Create button. We have typed the name
ZCL_MY_EMP_AREA. On the screen that appears, enter the description of the area. Also, enter the name of the
rootclass created earlier in the Root Class field. You may leave the Client-Specific Area checkbox unchecked as it is not required for our recipe. Now, save your entries. Refer to the following screenshot:
This will also generate an
areaclass by entering the same name
This area class will contain the necessary methods used for reading, changing, and creating the
area, such as ATTACH_FOR_UPDATE, ATTACH_FOR_READ, and ATTACH_FOR_WRITE.
Two object references
my_rootare defined, one for
areaclass and the other for
The static method
CREATE OBJECTwith the area handle,
my_handlemust then be called.
The root and the created area instance must be linked using the
set_rootmethod of the handle.
detach_commitmethod of the
areaclass is then called.
In the shared memory-writing program, the statements collectively make the writing of object in the shared memory. Let us see how the program code works.
An area instance version needs to be created before any data may be written in the shared memory on the application server. The
attach_for_write static method is used for this purpose and returns a handle to the area instance created in the application server memory. This imposes
write lock on the version.
CREATE OBJECT statement is then called with the name of the created handle. This creates a
root object in the
area instance of the shared memory. The link between the
area instance and the
root class is created using the
set_root method. The
set_data method is then called for the root reference
my_root and supplied with the name and number of the employee, which are then stored in the shared area. Finally, the
detach_commit method is called and the
write lock is released.
Once the program has run successfully, you may see the created object in the shared memory using the shared memory transaction
SHMM. This will appear as your area class name ZCL_MY_EMP_AREA. Refer to the following screenshot:
Double-click on the name of area to view the details, as shown in the following screenshot:
The read program is somewhat similar. However, instead of the
attach_for_write method used earlier, we will use
attach_for_read. The same instance name is passed and the handle is received. The method imposes a
read lock on the area instance. Then, the
get_data method of the
root object is called using the area handle,
my_handle. This returns the employee name and number stored earlier into the variables name and number respectively.
detach method is called and the
read lock is released.
While creating the shared memory area, if we select the Transactional Area checkbox, the area becomes transactional. In this case, the modifications to the
area instance versions are not active immediately after the call of
detach_commit method. Rather, they become active when the next database commit is executed.
ABAP objects provide a persistent object service that allows the developer to store objects in the database. The values of the attributes of the object are stored in appropriate fields of the database table specified. This recipe shows how to define
persistent classes and then how to call them in your application programs.
Prior to storing objects in the database, a suitable database table with the name
ZEMP_TABLE is created to store the values of the objects' attributes. Two fields are defined, NUMBER1 and NAME (the field name NUMBER was not allowed, so NUMBER1 has been used as the field name). Refer to the following screenshot:
Once the database table is defined, a
persistence class must be defined. In order to define
persistent classes, follow these steps:
SE24. Enter a suitable name of the
persistentclass to be created. We will create a class by entering the name
ZCL_MY_PERSIST. Enter the name in the Class field and click on the Create button.
Enter a suitable description in the field provided. Make sure that the Persistent Class indicator is selected, and click on Save.
The programmer may only modify the methods
Click on the Persistence button. Then, enter the name of the table that was created for storage of data( in our case, we will enter the name
ZEMP_TABLE). Refer to the following screenshot:
This will take you to the mapping editor. The lower part of the screen will show Table/Fields. Double-click each of the field that is to be included and stored as attributes of the
persistentclass. The selected field appears in the area earlier (for example, the NUMBER1 field as shown in the following screenshot). Click on the Set attribute values button to include the field.
This will transfer the selected field in the topmost area of the editor.
Similarly, the NAME field must be included.
All the mapped fields will appear at the top area of the mapper. The Number1 field will appear as a business key, as show in the following screenshot:
Upon activation of the
persistenceclass, the system asks for activation of the
actorclass as well. Click on Yes, as shown in the following screenshot:
ZCL_MY_PERSISTis created and necessary methods needed for the persistence service are included. An
actorclass is also created with the class. The agent class has been generated by the name
ZCA_MY_PERSIST. There is one
base agentclass generated as a result. In total, three classes are generated, the
agentclass, and the
baseclass of the agent.
ZCL_MY_PERSISTcontains methods for setting and getting the values of the attributes NAME and NUMBER1. Note that no SET method is generated for the key field, in our case NUMBER1.
agentclass provides number of useful methods related to the persistent property. Important methods, such as
get_persistentare provided. The methods are implemented in the superclass
During the generation of the
zcl_my_persist, two additional classes are generated. These are the
actor (agent) and the
base agent classes having the names
zcb_my_persist respectively. The
base agent class is generated as abstract (that is, no instance can be constructed from it), and cannot be modified. It is created in a separate pool class from
zca_my_persist may be extended, as well as the loading and saving methods may be modified.
The instantiation mode of the
persistence class may be set as abstract or protected. In our recipe, we have chosen the instantiation mode as protected (which means that only instances may be created from within the class or its subclasses). However, making the instantiation mode of a
persistent class as protected makes the generated
base agent class a friend of the
persistent class (in the world of ABAP objects, a friend or its subclasses may create instances of the class in question).
The coding for this recipe declares two references,
agent, to the
zcl_my_persist and the
zca_my_persist, respectively. Next, the
static factory method
agent is called for the class
agent class). The reference returned is stored in the variable
agent class contains the method
create_persistent required for storing the data into the database (this is analogous to the concept of insertion in database table).
The most important part is the calling of the
create_persistent method that is passed the number and name that is to be stored. The employee with the number
00000017 and name
John Reed is created and reference is returned in
emp. Finally, the
COMMIT WORK method stores the data of the
emp object into the table created earlier in this recipe. One row with the number and a name is added to the table
For reading the stored value related to the employee number
00000017, a number variable is declared and assigned the value
00000017. The static method agent of the
zca_my_persist class is called in order to get a reference to the
get_persistent method is then called and the number (in our case,
00000017) is passed. This method returns the entire object emp pertaining to the employee number. You may then call the
get_name method of the
zcl_my_persist class for the emp object in order to retrieve the employee name.
One important design pattern that is used in object-oriented ABAP is the factory design. This allows you to create objects of a particular class either via a
factory class or via
factory method defined within the class. The emphasis of this recipe is to design a class that supports the creation of its objects via a
factory method, rather than direct instantiation outside the class via
CREATE OBJECT statement.
factory method is a static method that creates and then returns (as a parameter) a reference to the object of the class it belongs to. The code for the creation of the object is contained within the
factory method. This recipe shows the factory design. You may further modify to enhance the structure in order to suit your needs
We have referred to the coding of the standard
cl_salv_table class factory method for creating the class shown in this recipe. The class created in this recipe will be used in the subsequent recipes of singleton and adapter design pattern.
For the sake of this recipe and the ones that follow, we will focus on an employee and name example. The class will encapsulate an eight-character number (in numeric form) for the employee number
00000014 and a 30-character field for the employee name. For example, there can be an employee
John Reed with number. This will be stored in the private attributes of the class as
For creating a class as a factory method design, follow these steps:
Create a class definition for
fac_meth_classin the program. The
factorymethod is a static method for the class and is defined via
CLASS-METHODS. The class definition contains the addition
create privatein order to stopthe instantiation of the class from outside via
CREATE OBJECT. A constructor is defined that allows setting the value of the number and the employee name.
The private attributes employee number and name are defined, as it is based on the dictionary data elements
The static method
factoryimports the name and number of the employee to be created and returns the employee object
employee_objof the object reference
fac_meth_class. The constructor takes as input the number and the employee name.
The implementation of the
fac_meth_classobject reference is then created. The code for the
constructoris written here. The
factorymethod receives the number and the name of the employee to be created. It includes the
CREATE OBJECTstatement for creation of the employee object.
The constructor assigns the number and employee name to the corresponding private attributes of the newly constructed object. A
WRITEstatement is also included that outputs the name and number of the successful created employee.
Finally, the call for the
factorymethod is included. The static method of the
fac_meth_class=>factory object is included and passed with the number and name of the employee to be created. A code shows two such method calls for object references
emp2, that is, employee
When the program calls the
static factory method, the code within the
factory method is called for each of the two objects
factory method triggers
CREATE OBJECT statement, which creates a new object and calls the constructor.
The constructor is called twice, once for each of the two instantiated objects
emp2. This prints the message successful creation for
singleton class is a class that can have only one instance at a time. Any attempt to create a second or more instances should not be allowed. This recipe shows how to create a class based on the singleton design.
We will use the same class created in the last recipe of
factory method. We will make few changes to the class so that we can prevent the creation of multiple instances of the class. We will make a copy of the class (program) shown in the previous recipe and modify it. The name of the copy is
For creating a
singleton class, follow these steps:
Make sure the
CREATE PRIVATEaddition is included in the
Within the definition, a static attribute
integeris added to the private section.
In the implementation of the
factorymethod now contains an
IFstatement that first checks the number of instances already there when the
factorycall is made. If the first instance is being created (that is,
number_of_instancesequals 0), the employee object is created and
number_of_instancesis set as
ELSEcondition is included to output a message if one instance already exists.
Similar to the previous recipe, we try to instantiate two objects
emp2, having number
00000014 respectively. However, in our
singleton class, we have added an attribute
number_of_instances, which keeps track of the number of class instances that already exist. Upon creation of the first object, the
factory method increments this static attribute to
1. On the second object creation attempt, the
IF statement does not allow the
CREATE OBJECT statement to be called a second time. The result is that the second object is not created. No further attempts of object creation will be allowed. Rather, a message saying that only one object instantiation is allowed is outputted for the second object creation attempt.
Another important design pattern is the adapter design. As the name suggests, the adapter design is used for conversion of one object into another object belonging to a different class. An
adapter class will have a method that takes as input the object reference that is to be converted and outputs it into the other object reference format.
We have referred to the
cl_salv_tree_adapter standard class while making of this recipe.
In order to demonstrate the adapter, we need two classes (
input class and
output class). The
input class will be the
fac_meth_class created earlier. For the output, we will create another class
fac_meth_class2. This will serve as the class, into the format of which the input object will be converted.
It is without a
factory method for sake of simplicity. It contains employee number and employee name but the format of these two is different from the classes shown in the previous recipes. The employee name of this class is based on data element
emnam, whereas the number is a character without zeros having length as eight. The name is of the form (
firstname lastname), meaning
John Reed will be stored as
John Reed and not Reed John as in the previous recipes. The constructor outputs the message,
Converted employee created.
We will use the same class used previously as the input object for the adapter method.
For creating a
singleton class, follow these steps:
Create a deferred definition of the
adapter_meth_classthat we are going to create in the next step.
adapter_meth_classas a friend of our
fact_meth_classclass in the definition via the
The implementation of the
adapterclass is then created. It contains the code of the
adaptermethod will convert the incoming number of the employee from numeric to character format. In addition, the name of the employee is converted to the
firstname lastnameformat. The new object based on the second class
fac_meth_class2is then created and returned as an exporting parameter of the method.
While calling the
adaptermethod, you first create an object based on the
fac_meth_classclass that is a
factorymethod (for illustrative purpose), similar to the previous recipe for the object reference
EMP. This is then passed on to the
static adaptermethod of the
adapterclass returns the converted object in the second format.
When the program calls the static method adapter of the class adapter_meth_class , the code in the adapter method is executed. The adapter method calls the necessary code for converting the number into the character format and any zeros are removed from the number. In addition, the SPLIT statement is called for converting name of the employee in the (first name last name) format such as converting Reed John into John Reed. Finally the CREATE OBJECT is called in order to create the object in the converted class format . This triggers the constructor for the converted class fac_meth_class2 that outputs the message "Converted: Employee Created having number 1234" and name John Reed. Since we called the factory method of the original fac_meth_class before the adapter method call, the original constructor was also called and message printed also.