Gyan Factory

Gyan Factory
SAP Technical Project Support

Tuesday, February 16, 2016

ABAP Objects Design Patterns – Abstract Factory

Abstract Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. Inherited subclasses of the abstract super class would know which of the objects are required.

Concept

Before jumping into the demo, lets see the concept. This will help us to better understand how Abstract Factory can be achieved.

UML

It looks little complicated, but its not. These are the Participants in this UML:
  • AbstractFactory: An interface with operations that creates abstract products
  • ConcreteFactory: Implementation of the AbstractFactory which creates actual products
  • AbstractProduct: An interface for each type of product object
  • ConcreteProduct: implementation of the AbstractProduct. This object would be created by respective concrete factory
  • Client: Creates object of the ConcreteFactory by using AbstractFactory interface

Design Time Consideration:

  1. Define an abstract superclass for the products.
  2. Inherit Subclasses from this super class as concrete products.
  3. Define an abstract superclass with abstract methods to create specific products
  4. Inherit Subclasses from this class as Concrete factories which would instantiate product objects as desired.

Demo

Let’s see the demo now. After going through the concepts it would be easier to understand the demo application.

Demo UML

For demo purpose, we’ll use this UML.
We have defined two product families, ABS_DATA and ABS_PRINT. Form ABS_DATA, we inherited two concrete products: DATA_FROM_FILE and DATA_FROM_DB. We also inherited two concrete products from ABS_PRINT, PRINT_SIMPLE and PRINT_ALV.
We have defined abstract factory class as REPORT. This has two abstract methods: GET_DATA( ) & PRINT_DATA( ). These methods would be redefined in the concrete factory classes: ComplexReport andSimpleReport. Complex Report uses DATA_FROM_DB and PRINT_ALV objects, whereas Simple Report uses DATA_FROM_FILE and PRINT_SIMPLE.

Code Lines

Here is the code snippet which achieves the Abstract Factory Design pattern.
REPORT znp_dp_abs_factory.

*=== .....
CLASS abs_data DEFINITION ABSTRACT.
  PUBLIC SECTION.
    METHODSread_data ABSTRACT.
ENDCLASS.                    "abs_data DEFINITION
*===
CLASS data_from_file DEFINITION INHERITING FROM abs_data.
  PUBLIC SECTION.
    METHODSread_data REDEFINITION.
ENDCLASS.                    "data_from_file DEFINITION
*
CLASS data_from_file IMPLEMENTATION.
  METHOD read_data.
    WRITE'Reading data from File'.
  ENDMETHOD.                    "read_data
ENDCLASS.                    "Data_from_file IMPLEMENTATION
*===
CLASS data_from_db DEFINITION INHERITING FROM abs_data.
  PUBLIC SECTION.
    METHODSread_data REDEFINITION.
ENDCLASS.                    "data_from_db DEFINITION
*
CLASS data_from_db IMPLEMENTATION.
  METHOD read_data.
    WRITE'Reading data from DATABASE TABLE'.
  ENDMETHOD.                    "read_data
ENDCLASS.                    "Data_from_db IMPLEMENTATION

*===....
CLASS abs_print DEFINITION ABSTRACT.
  PUBLIC SECTION.
    METHODSwrite_data ABSTRACT.
ENDCLASS.                    "abs_print DEFINITION
*===
CLASS print_alv DEFINITION INHERITING FROM abs_print.
  PUBLIC SECTION.
    METHODSwrite_data REDEFINITION.
ENDCLASS.                    "print_alv DEFINITION
*
CLASS print_alv IMPLEMENTATION.
  METHOD write_data.
    WRITE'Writing data into ALV'.
  ENDMETHOD.                    "write_data
ENDCLASS.                    "print_alv IMPLEMENTATION
*===
CLASS print_simple DEFINITION INHERITING FROM abs_print.
  PUBLIC SECTION.
    METHODSwrite_data REDEFINITION.
ENDCLASS.                    "print_simple DEFINITION
*
CLASS print_simple IMPLEMENTATION.
  METHOD write_data.
    WRITE'Writing data in classic - This is actually classic'.
  ENDMETHOD.                    "write_data
ENDCLASS.                    "print_simple IMPLEMENTATION

*=== ....
CLASS report DEFINITION ABSTRACT.
  PUBLIC SECTION.
    METHODSget_data ABSTRACT,
             print_data ABSTRACT.
ENDCLASS.                    "absfactory DEFINITION
*===
CLASS simplereport DEFINITION INHERITING FROM report.
  PUBLIC SECTION.
    METHODSget_data REDEFINITION.
    METHODSprint_data REDEFINITION.
ENDCLASS.                    "simplereport DEFINITION
*
CLASS simplereport IMPLEMENTATION.
  METHOD get_data.
    DATAlo_data TYPE REF TO data_from_file.
    CREATE OBJECT lo_data.
    lo_data->read_data).
  ENDMETHOD.                    "get_Data
  METHOD print_data.
    DATAlo_print TYPE REF TO print_simple.
    CREATE OBJECT lo_print.
    lo_print->write_data).
  ENDMETHOD.                    "print_data
ENDCLASS.                    "simplereport IMPLEMENTATION

*===
CLASS complexreport DEFINITION INHERITING FROM report.
  PUBLIC SECTION.
    METHODSget_data REDEFINITION.
    METHODSprint_data REDEFINITION.
ENDCLASS.                    "complexreport DEFINITION
*
CLASS complexreport IMPLEMENTATION.
  METHOD get_data.
    DATAlo_data TYPE REF TO data_from_db.
    CREATE OBJECT lo_data.
    lo_data->read_data).
  ENDMETHOD.                    "get_data
  METHOD print_data.
    DATAlo_print TYPE REF TO print_alv.
    CREATE OBJECT lo_print.
    lo_print->write_data).
  ENDMETHOD.                    "print_data
ENDCLASS.                    "complexreport IMPLEMENTATION

*===
CLASS lcl_main_app DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODSrun.
ENDCLASS.                    "lcl_main_app DEFINITION
*
CLASS lcl_main_app IMPLEMENTATION.
  METHOD run.
    DATAlo_report TYPE REF TO report.

*   Simple report (FILE + write)
    CREATE OBJECT lo_report TYPE simplereport.
    lo_report->get_data).
    lo_report->print_data).


*   report for DB in ALV
    CREATE OBJECT lo_report TYPE complexreport.
    lo_report->get_data).
    lo_report->print_data).

  ENDMETHOD.                    "run

ENDCLASS.                    "lcl_main_app IMPLEMENTATION

START-OF-SELECTION.
  lcl_main_app=>run).

Output

Output generated by the code snippet.

No comments:

Post a Comment