Factory Method design pattern could be most used design pattern in the modern world application. Factory method design pattern hides all the complexity of the instantiating an object from the consumer.
Page Contents
This DP provides an unique interface for object instantiation. This interface creates an object but let subclasses decide which class to instantiate.
Design time consideration:
- Create a Super Class with Factory method
- Create importing parameters: This would be used as conditions to define the subclass name
- Inherit the Subclasses from the Super class
- Define an object reference type to Super Class
UML:
For demo purpose, we will use this UML.
We have OPHANDLER which contains the FACTORY method. This method is Public and STATIC. This super class has another method called PROCESS_OUTPUT( ). We’ll also inherit some subclasses from the class OPHANDLER: OPHANDLER_ZABC to process ZABC output and OPHANDLER_ZXYZ to process ZXYZ output.
The FACTORY method has one importing parameter: Output Type and one Returning parameter, the object. Based on the requested output type, we’ll instantiate the object. For demo, I kept the implementation of FACTORY method simple: just calling CREATE OBJECT with TYPE of subclass.
Code Lines:
Lets see the code lines on how to implement this:
REPORT znp_dp_factory_method.
*&---------------------------------------------------------------------*
*& Purpose: Factory method Design Pattern
*& Author : Naimesh Patel
*&---------------------------------------------------------------------*
*=====
CLASS ophandler DEFINITION ABSTRACT.
PUBLIC SECTION.
CLASS-METHODS: factory
IMPORTING iv_output_type TYPE kschl
RETURNING value(ro_obj) TYPE REF TO ophandler.
METHODS: process_output ABSTRACT.
ENDCLASS. "ophandler DEFINITION
*=====
CLASS ophandler_zabc DEFINITION INHERITING FROM ophandler.
PUBLIC SECTION.
METHODS: process_output REDEFINITION.
ENDCLASS. "ophandler_zabc DEFINITION
*
CLASS ophandler_zabc IMPLEMENTATION.
METHOD process_output.
WRITE: / 'Processing ZABC'.
ENDMETHOD. "process_output
ENDCLASS. "ophandler_zabc IMPLEMENTATION
*
CLASS ophandler IMPLEMENTATION.
METHOD factory.
CASE iv_output_type.
WHEN 'ZABC'.
* This could be very complex logic to instantiate the object
* so, this wrapper will make sure all that complexity is
* hidden from the consumer.
CREATE OBJECT ro_obj TYPE ophandler_zabc.
WHEN 'ZXYZ'.
"create another object
WHEN OTHERS.
" raise exception
ENDCASE.
ENDMETHOD. "factory
ENDCLASS. "ophandler IMPLEMENTATION
*=====
CLASS lcl_main_app DEFINITION.
PUBLIC SECTION.
CLASS-METHODS: run.
ENDCLASS. "lcl_main_app DEFINITION
*
CLASS lcl_main_app IMPLEMENTATION.
METHOD run.
DATA: lo_output TYPE REF TO ophandler.
lo_output = ophandler=>factory( 'ZABC' ).
lo_output->process_output( ).
ENDMETHOD. "run
ENDCLASS. "lcl_main_app IMPLEMENTATION
START-OF-SELECTION.
lcl_main_app=>run( ).
SDN wiki – Factory Method Design Pattern
[…] purpose of the Factory method is to provide a new instance of the object whenever the Factory method is being called. When […]
Naimesh:
I have a question on Factory Method Design pattern….based on the link http://zevolving.com/2011/10/abap-objects-design-patterns-factory-method/#Design_time_consideration.
The question over here is….Suppose if i have a new method specific for the class ophandler_zabc say sort_output but it is not part of abstract class ophandler….
Then how do i call the new method in class lcl_main_app…because the object reference is of ophandler and it certainly does not identify the new method of ophandler_zabc?
If we try to type-cast the object reference it….it works! But will that be a design flow….or should the class that inherits the abstract class have methods identical to ones in abstract class?
This may be a silly question….but would be awaiting your comments.
Hello Vineesh,
Since the method is not available in the Super Class OPHANDLER, you wont be able to call it in class LCL_MAIN_APP. Certainly you can do casting but, that would introduce a condition in the class LCL_MAIN_APP. That would limit the functionality to only certain outputs.
On the other hand, if you add a method in OPHANDLER and redefine in your required class, you can seamlessly access that method via object of OPHANDLER.
SO, next question would be, do you make it abstract or non-abstract. If you make it abstract than you MUST redefine that method in ALL subclasses of OPHANDLER. It would be ideal but sometimes may not be practical as you have 10s of subclasses and you would need to retest all of them as you are “touching” them. In this type of situation, I would suggest, you make it a normal method with empty implementation, Redefine that method in your required class and you would be able to get the required results.
Thanks,
Naimesh Patel