UPDATE:This blog post has been updated with clear example demo on 12/17/2009. So, there could be some comments which would be obsolete.
Page Contents
What is the Singleton design pattern?
The concpet of restricting the instantiation of the a class to only and only to one object is called Singleton. As name suggests, it will restrict to create only one instance of a class. The calss will have a logic in place which will deny if the application will ask for more than one instance.
Code Lines
Let’s try to understand with an example:
We have an application which will bring the pay stub of an employee for current month. In a standarad system, there will be only one active salary account for the employee with the company. Because of this fact, we should only create one object of the employee’s salary account. In program, we are creating this object in a loop. So, what happens if we don’t have a design pattern which will restrict it to create more than one object. Application will create, rather overwrite an instance of the class.
In ABAP, generally we check if the instance is created or not, like:
Code Snippet to check instance
*&---------------------------------------------------------------------*
DATA: lo_application TYPE REF TO lcl_application.
IF lo_application IS BOUND.
CREATE OBJECT lo_application.
ENDIF.
But, if we take another reference to the class and create a instance of that, it will definatly allow. So, we need to have Singleton design pattern implemented.
How to implement Singleton design Pattern in ABAP?
We can use the CLASS-DATA(static data) to save the created instance within the class and check with that instance, if application asks for a new instance.
Code Snippet:
*&---------------------------------------------------------------------*
*& Report shows how to use the static data of the class to
*& implement the design patterns.
*&---------------------------------------------------------------------*
REPORT ztest_singleton_pattern.
*
*----------------------------------------------------------------------*
* CLASS lcl_application DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_application DEFINITION CREATE PRIVATE.
*
PUBLIC SECTION.
* Static Method which will return us the object reference
CLASS-METHODS:
get_apps_instance
RETURNING
value(ro_apps) TYPE REF TO lcl_application.
*
METHODS:
set_v_name
IMPORTING
iv_name TYPE char30,
get_v_name
RETURNING
value(rv_name) TYPE char30.
*
PRIVATE SECTION.
* static class reference to hold the existing object reference
CLASS-DATA: lo_apps TYPE REF TO lcl_application.
*
DATA: v_name TYPE char30.
*
ENDCLASS. "lcl_application DEFINITION
*
*
*----------------------------------------------------------------------*
* CLASS lcl_application IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_application IMPLEMENTATION.
*
* This method will return the object reference to the calling application
METHOD get_apps_instance.
IF lo_apps IS INITIAL.
* creation of the object
CREATE OBJECT lo_apps.
ENDIF.
* assigning reference back to exporting parameter
ro_apps = lo_apps.
ENDMETHOD. "get_apps_instance
*
METHOD set_v_name.
me->v_name = iv_name.
ENDMETHOD. "set_v_name
*
METHOD get_v_name.
rv_name = me->v_name.
ENDMETHOD. "get_v_name
*
ENDCLASS. "lcl_application IMPLEMENTATION
*
*
START-OF-SELECTION.
*
*.Reference: 1 .........................................
DATA: lo_application TYPE REF TO lcl_application.
DATA: lv_result TYPE char30.
*
WRITE: / 'LO_APPLICATION: '.
* calling the method which gets us the instance
* Statement CREATE OBJECT LO_APPLICATION
* would not work as the class LCL_APPLICATION instantiation
* is set to PRIVATE
lo_application = lcl_application=>get_apps_instance( ).
* Set the variable and get it back.
lo_application->set_v_name( 'This is first Object' ).
lv_result = lo_application->get_v_name( ).
WRITE: / lv_result.
CLEAR lv_result.
*
*.Reference: 2............................................
DATA: lo_2nd_apps TYPE REF TO lcl_application.
SKIP 2.
WRITE: / 'LO_2ND_APPS : '.
* calling the method which gets us the instance
* By calling GET_APPS_INSTANCE method again to get the singleton
* object, it would give the same object back and assign it to
* LO_2ND_APPS object reference. This would be varified by
* getting the value of the instance attribute V_NAME
lo_2nd_apps = lcl_application=>get_apps_instance( ).
lv_result = lo_2nd_apps->get_v_name( ).
WRITE: / lv_result.
CLEAR lv_result.
Update – Singleton Usage
Recently, I have posted another article on Singleton – ABAP Objects Design Patterns Singleton Usage. This article demonstrates step by step Singleton implementation along with UML sequence diagram.
SDN Wiki – Singleton design pattern
Check out all Design Patterns
You may also want to explore all other Design Patterns in OO ABAP.
- ABAP Object Design Patterns – Singleton
- ABAP Objects Design Patterns – Model View Controller (MVC) Part 1
- ABAP Objects Design Patterns – Model View Controller (MVC) Part 2
- ABAP Objects Design Patterns – Model View Controller (MVC) Part 3
- ABAP Objects Design Patterns – Decorator
- ABAP Objects Design Patterns – Factory Method
- ABAP Objects Design Patterns – Observer
- Case Study: Observer Design Pattern Usage
- ABAP Objects Design Patterns – Abstract Factory
- OO Design Pattern Decorator – Why do we need to use helper variable?
- ABAP Objects Design Patterns – Facade
- ABAP Objects Design Patterns – Adapter
- ABAP Objects Design Patterns – Composite
- ABAP Objects Design Patterns – Iterator
- Iterator Design Pattern to access Linked List in ABAP Objects
- ABAP Objects Design Patterns – Proxy
- ABAP Objects Design Patterns – Prototype
- ABAP Objects Design Patterns – Singleton Factory
- ABAP Object Oriented Approach for Reports – Initial Design
- ABAP Object Oriented Approach for Reports – Redesign
- ABAP Objects Design Patterns – Builder
- ABAP Objects Design Patterns Singleton Usage
- ABAP MVC – Model View Controller Discussion
- Object Oriented Approach for Reports with multiple Datasource
- OO ABAP – Selection Object with Direct Access
- OO ABAP – Selection Criteria Object using RS_REFRESH_FROM_SELECT OPTIONS
- ABAP Factory Method Using SWITCH
Is this singleton? I still can create another object by using “create object”. so I think it must have “create private” addition in class definition. Thanks!
Hello,
Anonymous said…
Is this singleton? I still can create another object by using “create object”. so I think it must have “create private” addition in class definition. Thanks!Thanks for pointing out. It’s been corrected now.
Regards,
Naimesh Patel
Hi,
I've tried your code but the 2nd reference is not initial. I think the concept is applied correctly but the explanation is a bit off. In ABAP, object reference are in fact, pointers. Therefore when the 2nd object reference LO_2ND_APPS is being "assigned" by calling the class method GET_APPS_INSTANCE, the class method simply returns the reference of the instantiated object reference. This means that both LO_APPLICATION and LO_2ND_APPS are referencing or pointing to the same instance, which is why the end result is LO_2ND_APPS is not initial as you have written.
The singleton design is achieved perfectly in the class definition and implementation. Only the demonstration of how a singleton works is a bit off. You should've just show that the following code is not possible:
CREATE OBJECT lo_2nd_apps.
..which will return a syntax error because of the class definition having the addition CREATE PRIVATE.
You can also demonstrate how the two object references LO_APPLICATION and LO_2ND_APPS are in fact referencing the same instantiation by adding another "attribute" to the class. Change the attribute using LO_APPLICATION and display that value using LO_2ND_APPS. That should be sufficient enough to prove that this singleton works.
Hope this clears up some confusion (including mine).
Regards,
Fadhlul
If I use the above code I could create another object. your get_apps_instance should be like
METHOD get_apps_instance.
IF lo_apps IS INITIAL.
* create of the object
CREATE OBJECT lo_apps.
* assigning reference back to exporting paramenter
eo_apps = lo_apps.
ENDIF.
ENDMETHOD. "get_apps_instance
Hello All,
I have recently updated this blog post to provide good view of the singleton design pattern.
Thanks for all who provided the feedback, especially to Fadhlul.
Regards,
Naimesh Patel
this is really help full for me.plz give me more example
I think if we instantiate the private class in a static constructor we'l be able to obtain the singleton principle as the static constructor is called only once when the first time we instantiate.
Correct me if m wrong.
-Sunil
Hello Sunil,
"I think if we instantiate the private class in a static constructor we'l be able to obtain the singleton principle as the static constructor is called only once when the first time we instantiate."
Yes, we can achieve the singleton by instantiating the object within the CLASS_CONSTRUCTOR. But, if we don't design the class properly, this approach would have higher cost.
Refer to my post CLASS_CONSTRUCTOR and CONSTRUCTOR: Who comes before whom?. You can notice that any access to Static component will call the CLASS_CONSTRUCTOR. So, if your class has any constant in it and if any program uses that constant, it will unnecessarily instantiate the Singleton object which it might not need at all…
Regards,
Naimesh Patel
The design pattern is correct in theory and implementation but the example is wrong in practice. What if you have 2 or more employees? Using the Singleton pattern to limit the creation of the class would prevent you from creating it for other employee data. Once the object is created with an employee’s data perhaps you wouldn’t want to create it again, but now you’re talking about a Factory pattern.
Hello DP-Wizard,
Yes – singleton and factory both has its on purpose. When you are working with a specific document in a session like a Sales order and you wish to use the same data when you are working with the same Sales Order, than you use the Singleton. But when you want to have separate object for each sales order as you are mass processing them, you should use Factory to create a collection of objects using composite.
Regards,
Naimesh Patel
[…] purpose of the Singleton Design pattern is to return the same object over and over to the caller. Singleton would be useful […]
this blog can only understand by the persons who have experiance over a decade like you…….