ABAP Factory Method Design Pattern

Summary: in this tutorial, you will learn what is ABAP factory method design pattern and how to implement the factory method in ABAP.

Problems

You want to abstract the process of creating objects so the type of object created can be specified at run-time.

Intent

  • Provide an interface for creating new objects, but lets subclasses decide what kind of object to create. Factory Method allows a class to defer instantiation to subclasses.
  • CREATE OBJECT is considered harmful.

ABAP Factory Method UML Diagram

The following UML diagram illustrates the factory method. There are four classes:

  • Creator. The Creator class is an abstract base class for all ConcreteCreator classes which will truly create new objects. In the diagram, this class can be replaced by an interface that contains the factory method signature. In this case, all subclasses will implement this interface.
  • ConcreteCreator. This is a subclass that inherits all functionalities of the Creator base class. You can implement the logic for creating actual objects here. In the diagram, the ConcreteCreator class is in charge of creating the object of ConcreateProduct class.
  • Product. The Product is an abstract class. This class is a base class for all object types which the factory class creator can create therefore it is a return type of the factory method. You can replace this abstract class by an interface if no common functionality is to be inherited by its subclasses.
  • ConcreteProduct. You can define multiple subclasses of the Product as ConcreateProduct that contains specific functionality. Objects of ConcreateProduct classes are created by the factory method.
Factory Method Design Pattern UML
Factory Method Design Pattern UML

ABAP Factory Method Implementation

We are going to implement ABAP factory method pattern as the following UML diagram:

ABAP Factory Method Design Pattern UML Diagram
ABAP Factory Method Design Pattern UML Diagram

On the left side of the diagram, we have class LCL_SALE_DOCUMENT that is a super class for all sale documents. The quotation and order classes inherit all functionalities of the sale document class. For demonstration, we use only write() method to output a message for quotation and order. The class LCL_SALE_DOCUMENT is equivalent to the class Product in the above UML diagram. The class LCL_QUOTATION and class LCL_ORDER are equivalent to the class ConcreateProduct.

On the right side of the diagram, we have an interface LIF_SALE_DOCUMENT_FACTORY that has a factor method create() that creates LCL_SALE_DOCUMENT instances. The class LCL_SALE_DOCUMENT_FACTORY implements the interface LIF_SALE_DOCUMENT_FACTORY and contains actual logic for creating LCL_SALE_DOCUMENT objects.

The following ABAP code illustrates the ABAP Factory Method UML diagram above:

*---------------------------------------------------------------------*
* Report  ZDP_FACTORY_METHOD
*
*---------------------------------------------------------------------*
* Description    : This program demonstrates ABAP Factory Method
*                  Design Pattern
* Program Author : ABAPTutorial.com
*---------------------------------------------------------------------*

REPORT  zdp_factory_method.

*----------------------------------------------------------------------*
*       CLASS lcl_sale_document DEFINITION
*----------------------------------------------------------------------*
* Sale document
*----------------------------------------------------------------------*
CLASS lcl_sale_document DEFINITION ABSTRACT.
  PUBLIC SECTION.
    METHODS: write ABSTRACT.
ENDCLASS.                    "lcl_sale_document DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_quotation  DEFINITION
*----------------------------------------------------------------------*
* Quotation
*----------------------------------------------------------------------*
CLASS lcl_quotation DEFINITION
      INHERITING FROM lcl_sale_document.
  PUBLIC SECTION.
    METHODS: write REDEFINITION.
ENDCLASS.                    "lcl_quotation  DEFINITIO

*----------------------------------------------------------------------*
*       CLASS lcl_quotation IMPLEMENTATION
*----------------------------------------------------------------------*
* Quotation implementation
*----------------------------------------------------------------------*
CLASS lcl_quotation IMPLEMENTATION.
  METHOD write.
    WRITE: 'Quotation'.
  ENDMETHOD.                    "write
ENDCLASS.                    "lcl_quotation IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS lcl_order  DEFINITION
*----------------------------------------------------------------------*
* Sale order
*----------------------------------------------------------------------*
CLASS lcl_order DEFINITION
      INHERITING FROM lcl_sale_document.
  PUBLIC SECTION.
    METHODS: write REDEFINITION.
ENDCLASS.                    "lcl_order  DEFINITIO

*----------------------------------------------------------------------*
*       CLASS lcl_order IMPLEMENTATION
*----------------------------------------------------------------------*
* Sale Order implementation
*----------------------------------------------------------------------*
CLASS lcl_order IMPLEMENTATION.
  METHOD write.
    WRITE: 'Order'.
  ENDMETHOD.                    "write
ENDCLASS.                    "lcl_order IMPLEMENTATION

*----------------------------------------------------------------------*
*       INTERFACE lif_sale_document_factory IMPLEMENTATION
*----------------------------------------------------------------------*
* Sale document factor interface
*----------------------------------------------------------------------*
INTERFACE lif_sale_document_factory.
  METHODS:
        create IMPORTING im_docty TYPE vbtyp
              RETURNING value(re_doc) TYPE REF TO lcl_sale_document.
ENDINTERFACE.                    "lif_sale_document_factory IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS lcl_sale_document_factory DEFINITION
*----------------------------------------------------------------------*
* Sale document factory
*----------------------------------------------------------------------*
CLASS lcl_sale_document_factory DEFINITION.
  PUBLIC SECTION.
    INTERFACES:
      lif_sale_document_factory.
    ALIASES: create FOR lif_sale_document_factory~create.
ENDCLASS.                    "lcl_sale_document_factory DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_sale_document_factory IMPLEMENTATION
*----------------------------------------------------------------------*
* Sale document factory implementation
*----------------------------------------------------------------------*
CLASS lcl_sale_document_factory IMPLEMENTATION.
  METHOD create.
    DATA: lo_doc TYPE REF TO lcl_sale_document.
    CASE im_docty.
      WHEN 'B'.
        CREATE OBJECT lo_doc TYPE lcl_quotation.
      WHEN 'C'.
        CREATE OBJECT lo_doc TYPE lcl_order.
      WHEN OTHERS.
        " default, create order
        CREATE OBJECT lo_doc TYPE lcl_order.
    ENDCASE.
    re_doc = lo_doc.
  ENDMETHOD.                    "create
ENDCLASS.                    "lcl_sale_document_factory IMPLEMENTATION

DATA:
    go_doc TYPE REF TO lcl_sale_document,
    go_sale_document_factory TYPE REF TO lif_sale_document_factory.

PARAMETERS:
    pa_docty TYPE vbtyp. " B quotation, C order

START-OF-SELECTION.
  " create factory
  CREATE OBJECT go_sale_document_factory
      TYPE lcl_sale_document_factory.

  " create sale document at runtime.
  go_doc = go_sale_document_factory->create( pa_docty ).
  go_doc->write( ).