REPORT zfactory_structural NO STANDARD PAGE HEADING LINE-SIZE 80.
CLASS cl_abap_typedescr DEFINITION LOAD.
DATA: moff TYPE i ,slen TYPE i ,mlen TYPE i.
DEFINE ?get_class_name.
&2 = cl_abap_classdescr=>get_class_name( &1 ).
find regex 'CLASS=' in &2 match offset moff match length mlen.
slen = moff + mlen.
shift &2 by slen places left.
END-OF-DEFINITION.
INTERFACE product.
TYPES ty_productname(30) TYPE c.
DATA: name TYPE ty_productname.
METHODS:
get_name RETURNING value(name) TYPE ty_productname.
ENDINTERFACE.
CLASS concreteproducta DEFINITION.
PUBLIC SECTION.
INTERFACES:
product.
ENDCLASS. "concreteproducta DEFINITION CLASS concreteproducta IMPLEMENTATION.
METHOD product~get_name.
name = 'ConcreteProductA'.
ENDMETHOD. "product~getname
ENDCLASS. "concreteproducta IMPLEMENTATION CLASS concreteproductb DEFINITION.
Project: Design Pattern
PUBLIC SECTION.
INTERFACES:
product.
ENDCLASS. "concreteproductB DEFINITION CLASS concreteproductb IMPLEMENTATION.
METHOD product~get_name.
name = 'ConCreteProductB'.
ENDMETHOD. "product~getname
ENDCLASS. "concreteproductB IMPLEMENTATION INTERFACE creator.
METHODS:
factorymethod RETURNING value(product) TYPE REF TO product.
ENDINTERFACE.
CLASS concretecreatora DEFINITION.
PUBLIC SECTION.
INTERFACES:
creator.
ENDCLASS. "concretecreatora DEFINITION CLASS concretecreatora IMPLEMENTATION.
METHOD creator~factorymethod.
CREATE OBJECT product TYPE concreteproducta.
ENDMETHOD. "factoryproduct
ENDCLASS. "concretecreatora IMPLEMENTATION CLASS concretecreatorb DEFINITION.
PUBLIC SECTION.
INTERFACES:
creator.
ENDCLASS. "concretecreatorb DEFINITION CLASS concretecreatorb IMPLEMENTATION.
METHOD creator~factorymethod.
CREATE OBJECT product TYPE concreteproductb.
ENDMETHOD. "factoryproduct
ENDCLASS. "concretecreatorb IMPLEMENTATION CLASS mainapp DEFINITION.
PUBLIC SECTION.
CLASS-DATA: oa_creator_coll TYPE TABLE OF REF TO creator.
CLASS-METHODS main.
ENDCLASS. "mainapp DEFINITION CLASS mainapp IMPLEMENTATION.
METHOD main.
data: concretecreatora TYPE REF TO concretecreatora ,concretecreatorb TYPE REF TO concretecreatorb ,product TYPE REF TO product
,product_name(30) type c
,class_name TYPE abap_abstypename .
FIELD-SYMBOLS <fs> TYPE REF TO creator.
CREATE OBJECT concretecreatora.
APPEND concretecreatora TO oa_creator_coll.
CREATE OBJECT concretecreatorb.
APPEND concretecreatorb TO oa_creator_coll.
LOOP AT oa_creator_coll ASSIGNING <fs>.
* Call macro to find out which Creator and Product are active ?get_class_name <fs> class_name.
Project: Design Pattern
CASE class_name.
WHEN 'CONCRETECREATORA'.
WRITE: / 'ConcreteCreatorA Creates Product A'.
WHEN 'CONCRETECREATORB'.
WRITE: / 'ConcreteCreatorB Creates Product B'.
ENDCASE.
product = <fs>->factorymethod( ) . ?get_class_name product class_name.
product_name = product->get_name( ).
WRITE: / 'Class= ', class_name,'Product =',product_name.
ENDLOOP.
ENDMETHOD. "main
ENDCLASS. "mainapp IMPLEMENTATION START-OF-SELECTION.
mainapp=>main( ).
Output
ConcreteCreatorA Creates ProductA Class =
CONCRETEPRODUCTA
Product = ConcreteProductA
ConcreteCreatorB Creates ProductB Class =
CONCRETEPRODUCTB
Product = ConcreteProductB
2.1.3.7 Sample code in ABAP
This real-world code demonstrates the Factory method offering flexibility in creating different documents. The derived Document classes Report and Resume instantiate extended versions of the Document class. Here, the Factory Method is called in the constructor of the Document derived class, in ABAP you cannot call an abstract method from the abstract base class
constructor.
REPORT zfactory_structural NO STANDARD PAGE HEADING LINE-SIZE 80.
CLASS cl_abap_typedescr DEFINITION LOAD.
DATA: moff TYPE i ,slen TYPE i ,mlen TYPE i.
DEFINE ?get_class_name.
&2 = cl_abap_classdescr=>get_class_name( &1 ).
find regex 'CLASS=' in &2 match offset moff match length mlen.
slen = moff + mlen.
shift &2 by slen places left.
END-OF-DEFINITION.
CLASS page DEFINITION ABSTRACT.
ENDCLASS. "page DEFINITION CLASS skillspage DEFINITION INHERITING FROM page.
ENDCLASS. "skillspage DEFINITION CLASS educationpage DEFINITION INHERITING FROM page.
Project: Design Pattern
ENDCLASS. "educationpage DEFINITION CLASS experiencepage DEFINITION INHERITING FROM page.
ENDCLASS. "experiencepage DEFINITION CLASS introductionpage DEFINITION INHERITING FROM page.
ENDCLASS. "introductionpage DEFINITION CLASS resultspage DEFINITION INHERITING FROM page.
ENDCLASS. "resultspage DEFINITION CLASS conclusionpage DEFINITION INHERITING FROM page.
ENDCLASS. "conclusionpage DEFINITION CLASS summarypage DEFINITION INHERITING FROM page.
ENDCLASS. "summarypage DEFINITION CLASS bibliographypage DEFINITION INHERITING FROM page.
ENDCLASS. "bibliographypage DEFINITION CLASS document DEFINITION ABSTRACT.
PUBLIC SECTION.
METHODS:
createpages ABSTRACT
,pages EXPORTING pages TYPE ANY TABLE .
PROTECTED SECTION.
DATA:
oa_pages_coll TYPE TABLE OF REF TO page.
ENDCLASS. "document DEFINITION CLASS document IMPLEMENTATION.
METHOD pages.
pages[] = oa_pages_coll[].
ENDMETHOD. "pages
ENDCLASS. "document IMPLEMENTATION CLASS resume DEFINITION INHERITING FROM document.
PUBLIC SECTION.
METHODS:
constructor
,createpages REDEFINITION.
ENDCLASS. "resume DEFINITION CLASS resume IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
CALL METHOD me->createpages.
ENDMETHOD. "constructor METHOD createpages.
DATA: page TYPE REF TO page.
CREATE OBJECT page TYPE skillspage.
APPEND page TO oa_pages_coll.
CREATE OBJECT page TYPE educationpage.
APPEND page TO oa_pages_coll.
CREATE OBJECT page TYPE experiencepage.
APPEND page TO oa_pages_coll.
ENDMETHOD. "createpages
ENDCLASS. "resume IMPLEMENTATION
Project: Design Pattern
CLASS report DEFINITION INHERITING FROM document.
PUBLIC SECTION.
METHODS:
constructor
,createpages REDEFINITION.
ENDCLASS. "report DEFINITION CLASS report IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
CALL METHOD me->createpages.
ENDMETHOD. "constructor METHOD createpages.
DATA: page TYPE REF TO page.
CREATE OBJECT page TYPE introductionpage.
APPEND page TO oa_pages_coll.
CREATE OBJECT page TYPE resultspage.
APPEND page TO oa_pages_coll.
CREATE OBJECT page TYPE conclusionpage.
APPEND page TO oa_pages_coll.
CREATE OBJECT page TYPE summarypage.
APPEND page TO oa_pages_coll.
CREATE OBJECT page TYPE bibliographypage.
APPEND page TO oa_pages_coll.
ENDMETHOD. "createpages
ENDCLASS. "report IMPLEMENTATION CLASS mainapp DEFINITION.
PUBLIC SECTION.
CLASS-DATA: oa_document_coll TYPE TABLE OF REF TO document.
CLASS-METHODS main.
ENDCLASS. "mainapp DEFINITION CLASS mainapp IMPLEMENTATION.
METHOD main.
DATA: document TYPE REF TO document ,resume TYPE REF TO resume ,report TYPE REF TO report ,page TYPE REF TO page ,class_name TYPE abap_abstypename ,pages_coll TYPE TABLE OF REF TO page.
.
FIELD-SYMBOLS: <fs_document> TYPE REF TO document ,<fs_page> TYPE REF TO page.
CREATE OBJECT resume.
APPEND resume TO oa_document_coll.
CREATE OBJECT report.
APPEND report TO oa_document_coll.
* Loop at all documents
LOOP AT oa_document_coll ASSIGNING <fs_document>.
* Call macro to find out which Creator and Product are active ?get_class_name <fs_document> class_name.
CASE class_name.
WHEN 'RESUME'.
WRITE: / 'Resume contains following pages:', / sy-uline.
CALL METHOD <fs_document>->pages( IMPORTING pages = pages_coll ).
* Loop at all pages in document Resume
Project: Design Pattern
LOOP AT pages_coll ASSIGNING <fs_page>.
?get_class_name <fs_page> class_name.
WRITE: / class_name.
ENDLOOP.
WHEN 'REPORT'.
WRITE: / 'Report contains following pages:', / sy-uline.
CALL METHOD <fs_document>->pages( IMPORTING pages = pages_coll ).
* Loop at all pages in document Resume LOOP AT pages_coll ASSIGNING <fs_page>.
?get_class_name <fs_page> class_name.
WRITE: / class_name.
ENDLOOP.
ENDCASE.
ENDLOOP.
ENDMETHOD. "main
ENDCLASS. "mainapp IMPLEMENTATION START-OF-SELECTION.
mainapp=>main( ).
Output:
Resume contains following pages:
SKILLSPAGE EDUCATIONPAGE EXPERIENCEPAGE Report contains following pages:
INTRODUCTIONPAGE RESULTSPAGE CONCLUSIONPAGE SUMMARYPAGE BIBLIOGRAPHYPAGE