Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Design Patterns, The Decorator

Former Member
0 Likes
1,250

When trying to implement the classic decorator design patterns your decorator executable might look like this:<br><br>

<pre>

METHOD validate.

DATA: Validator TYPE REF TO validation_manager.

CREATE OBJECT:

Validator TYPE validation_manager.

,Validator TYPE validate_format EXPORTING x_validator = Validator

,Validator TYPE validate_values EXPORTING x_validator = Validator

,Validator TYPE validate_relation_input EXPORTING x_validator = Validator

,Validator TYPE validate_relation_database EXPORTING x_validator = Validator.

me->lst_result = validator->validate( me->lst_data ).

WRITE: / 'Processing Validate Activity'.

ENDMETHOD. "validate</pre><br><br>

The validate method ends up in endless resurcion in the memory. The reason is that I'm using the same variable as the resulting instanse and as parameter. It seems like the constructor treats both the result and the parameter as the same field/instanse regardless import parameter such as VALUE/REFERENCE. If I change the method to use an extra field in the method validate like:

<br><br><pre>

METHOD validate.

DATA:

validator TYPE REF TO validation_manager

,recursive TYPE REF TO validation_manager.

CREATE OBJECT validator TYPE validation_manager.

recursive ?= validator.

CREATE OBJECT validator TYPE validate_format

EXPORTING x_validator = recursive.

recursive ?= validator.

CREATE OBJECT validator TYPE validate_values

EXPORTING x_validator = recursive.

recursive ?= validator.

CREATE OBJECT validator TYPE validate_relation_input

EXPORTING x_validator = recursive.

recursive ?= validator.

CREATE OBJECT validator TYPE validate_relation_database

EXPORTING x_validator = recursive .

recursive ?= validator.

me->lst_result = validator->validate( me->lst_data ).

WRITE: / 'Processing Validate Activity'.

ENDMETHOD. "validate</pre><br><br>

Now the decorator engine works, but why does the first implementation not work when the same one executes fine in php, c++, delphi, java and other languages.<br><br>

If you do not know what I'm trying to discuss, look up "Design Patterns - Simply", and jump to the chapter about the decorator design pattern. I'm trying to use this design pattern for a validation manager within my Business Process Engine, which needs to be able to configure what types of validation needed for on specific process (BPMN).<br><br>

1 ACCEPTED SOLUTION
Read only

naimesh_patel
Active Contributor
0 Likes
1,103

It goes into endless LOOP because when system executes this statement it carries the new object created in the X_VALIDATOR parameter. So, the object has the reference of its OWN object instead of the SUPER object. This happens because as soon as system executes the statement CREATE OBJECT it creates the object before calling the constructor. SO, when it reaches to constructor it has its OWN object reference instead of the SUPER object reference.


      CREATE OBJECT:
        validator TYPE validation_manager
       ,Validator TYPE validate_format                 EXPORTING x_validator = Validator

From Help:

The CREATE OBJECT statement creates an instance of a class or object and assigns the object reference to the reference variable oref. Directly after the object has been created, the instance constructor of the class is executed.

http://help.sap.com/abapdocu_70/en/ABAPCREATE_OBJECT.htm

So, you need to use the temporary variable to hold the super's reference and pass this variable while instantiating the object.

Regards,

Naimesh Patel

When trying to implement the classic decorator design patterns your decorator executable might look like this:<br><br>

<pre>

METHOD validate.

DATA: Validator TYPE REF TO validation_manager.

CREATE OBJECT:

Validator TYPE validation_manager.

,Validator TYPE validate_format EXPORTING x_validator = Validator

,Validator TYPE validate_values EXPORTING x_validator = Validator

,Validator TYPE validate_relation_input EXPORTING x_validator = Validator

,Validator TYPE validate_relation_database EXPORTING x_validator = Validator.

me->lst_result = validator->validate( me->lst_data ).

WRITE: / 'Processing Validate Activity'.

ENDMETHOD. "validate</pre><br><br>

The validate method ends up in endless resurcion in the memory. The reason is that I'm using the same variable as the resulting instanse and as parameter. It seems like the constructor treats both the result and the parameter as the same field/instanse regardless import parameter such as VALUE/REFERENCE. If I change the method to use an extra field in the method validate like:

<br><br><pre>

METHOD validate.

DATA:

validator TYPE REF TO validation_manager

,recursive TYPE REF TO validation_manager.

CREATE OBJECT validator TYPE validation_manager.

recursive ?= validator.

CREATE OBJECT validator TYPE validate_format

EXPORTING x_validator = recursive.

recursive ?= validator.

CREATE OBJECT validator TYPE validate_values

EXPORTING x_validator = recursive.

recursive ?= validator.

CREATE OBJECT validator TYPE validate_relation_input

EXPORTING x_validator = recursive.

recursive ?= validator.

CREATE OBJECT validator TYPE validate_relation_database

EXPORTING x_validator = recursive .

recursive ?= validator.

me->lst_result = validator->validate( me->lst_data ).

WRITE: / 'Processing Validate Activity'.

ENDMETHOD. "validate</pre><br><br>

Now the decorator engine works, but why does the first implementation not work when the same one executes fine in php, c++, delphi, java and other languages.<br><br>

If you do not know what I'm trying to discuss, look up "Design Patterns - Simply", and jump to the chapter about the decorator design pattern. I'm trying to use this design pattern for a validation manager within my Business Process Engine, which needs to be able to configure what types of validation needed for on specific process (BPMN).<br><br>

6 REPLIES 6
Read only

matt
Active Contributor
0 Likes
1,103

Fixed your formatting for you.

Read only

matt
Active Contributor
0 Likes
1,103

Could you also post the constructor.

matt

Read only

Former Member
0 Likes
1,103

Hi Matt, Thanks for the formatting..:) I will post the complete program as it's only a prototype program. Trying to get the format under control.

</body>

}*----


*

  • Report ZDP_DECORATOR_XMP01

*----


*

REPORT zdp_decorator_xmp01.

parameters: bestimpl TYPE boolean_01 default 0.

TYPES:

BEGIN OF processdata

,name TYPE char30

,street TYPE char30

,zip TYPE char5

,city TYPE char30

,email TYPE char50

,phone TYPE char20

,END OF processdata

,BEGIN OF result

,msgid TYPE msgid

,msgtyp TYPE msgty

,msgno TYPE msgno

,status TYPE char1

,END OF result.

CONSTANTS:

true TYPE boolean_01 VALUE 1

,false TYPE boolean_01 VALUE 0.

*----


*

  • CLASS validationmanager DEFINITION

*----


*

CLASS validation_manager DEFINITION.

PUBLIC SECTION.

METHODS:

validate

IMPORTING

x_data TYPE processdata

RETURNING

value(y_result) TYPE result.

ENDCLASS.

*----


*

  • CLASS validationmanager IMPLEMENTATION

*----


*

CLASS validation_manager IMPLEMENTATION.

METHOD validate.

WRITE: / 'Common validation'.

ENDMETHOD. "validate

ENDCLASS.

*----


*

  • CLASS Validate_Decorator DEFINITION

*----


*

CLASS validate_decorator DEFINITION INHERITING FROM validation_manager ABSTRACT .

PUBLIC SECTION.

DATA: validator TYPE REF TO validation_manager.

ENDCLASS.

*----


*

  • CLASS validate_format DEFINITION

*----


*

CLASS validate_format DEFINITION INHERITING FROM validate_decorator.

PUBLIC SECTION.

METHODS:

constructor

IMPORTING value(x_validator) TYPE REF TO validation_manager

,validate REDEFINITION.

ENDCLASS.

*----


*

  • CLASS validate_format IMPLEMENTATION

*----


*

CLASS validate_format IMPLEMENTATION.

METHOD constructor.

CALL METHOD super->constructor( ).

me->validator = x_validator.

ENDMETHOD. "constructor

METHOD validate.

y_result = validator->validate( x_data ).

IF y_result-status IS INITIAL.

WRITE: / 'Now doing the format checks'.

ENDIF.

ENDMETHOD. "validate

ENDCLASS.

*----


*

  • CLASS validate_values DEFINITION

*----


*

CLASS validate_values DEFINITION INHERITING FROM validate_decorator.

PUBLIC SECTION.

METHODS:

constructor

IMPORTING value(x_validator) TYPE REF TO validation_manager

,validate REDEFINITION.

ENDCLASS.

*----


*

  • CLASS validate_values IMPLEMENTATION

*----


*

CLASS validate_values IMPLEMENTATION.

METHOD constructor.

CALL METHOD super->constructor( ).

me->validator = x_validator.

ENDMETHOD. "constructor

METHOD validate.

y_result = validator->validate( x_data ).

IF y_result-status IS INITIAL.

WRITE: / 'Now doing the values checks'.

ENDIF.

ENDMETHOD. "validate

ENDCLASS.

*----


*

  • CLASS validate_relation_input DEFINITION

*----


*

CLASS validate_relation_input DEFINITION INHERITING FROM validate_decorator.

PUBLIC SECTION.

METHODS:

constructor

IMPORTING value(x_validator) TYPE REF TO validation_manager

,validate REDEFINITION.

ENDCLASS.

*----


*

  • CLASS validate_relation_input IMPLEMENTATION

*----


*

CLASS validate_relation_input IMPLEMENTATION.

METHOD constructor.

CALL METHOD super->constructor( ).

me->validator = x_validator.

ENDMETHOD. "constructor

METHOD validate.

y_result = validator->validate( x_data ).

IF y_result-status IS INITIAL.

WRITE: / 'Now doing the relation input checks'.

ENDIF.

ENDMETHOD. "validate

ENDCLASS.

*----


*

  • CLASS validate_relation_database DEFINITION

*----


*

CLASS validate_relation_database DEFINITION INHERITING FROM validate_decorator.

PUBLIC SECTION.

METHODS:

constructor

IMPORTING value(x_validator) TYPE REF TO validation_manager

,validate REDEFINITION.

ENDCLASS.

*----


*

  • CLASS validate_relation_database IMPLEMENTATION

*----


*

CLASS validate_relation_database IMPLEMENTATION.

METHOD constructor.

CALL METHOD super->constructor( ).

me->validator = x_validator.

ENDMETHOD. "constructor

METHOD validate.

y_result = validator->validate( x_data ).

IF y_result-status IS INITIAL.

WRITE: / 'Now doing the relation database checks'.

ENDIF.

ENDMETHOD. "validate

ENDCLASS.

*----


*

  • CLASS process_execution DEFINITION

*----


*

CLASS process_execution DEFINITION.

PUBLIC SECTION.

METHODS:

startevent

,getdata

,validate

,process

,endevent.

PRIVATE SECTION.

DATA:

lst_data TYPE processdata

,lst_result TYPE result.

ENDCLASS. "process_execution DEFINITION

*----


*

  • CLASS process_execution IMPLEMENTATION

*----


*

CLASS process_execution IMPLEMENTATION.

METHOD startevent.

WRITE: / 'Processing startevent'.

ENDMETHOD. "startevent

METHOD getdata.

me->lst_data-name = 'Hans Andersen'.

me->lst_data-street = 'H.C Andersens Boulevard 112'.

me->lst_data-zip = '1557'.

me->lst_data-city = 'København'.

me->lst_data-email = 'hcATandersen.dk'.

me->lst_data-phone = '0045-31162211'.

WRITE: / 'Processing Get_Data Activity'.

ENDMETHOD. "getdata

*----


*

*----


*

METHOD validate.

DATA:

validator TYPE REF TO validation_manager

,recursive TYPE REF TO validation_manager

.

IF bestimpl = true.

CREATE OBJECT:

validator TYPE validation_manager

,validator TYPE validate_format EXPORTING x_validator = recursive

,validator TYPE validate_values EXPORTING x_validator = recursive

,validator TYPE validate_relation_input EXPORTING x_validator = recursive

,validator TYPE validate_relation_database EXPORTING x_validator = recursive.

ELSE.

CREATE OBJECT validator TYPE validation_manager.

recursive ?= validator.

CREATE OBJECT validator TYPE validate_format

EXPORTING x_validator = recursive.

recursive ?= validator.

CREATE OBJECT validator TYPE validate_values

EXPORTING x_validator = recursive.

recursive ?= validator.

CREATE OBJECT validator TYPE validate_relation_input

EXPORTING x_validator = recursive.

recursive ?= validator.

CREATE OBJECT validator TYPE validate_relation_database

EXPORTING x_validator = recursive .

recursive ?= validator.

ENDIF.

  • Recursive call of the validate and it's successors

me->lst_result = validator->validate( me->lst_data ).

WRITE: / 'Processing Validate Activity'.

ENDMETHOD. "validate

METHOD process.

WRITE: / 'Processing Process Activity'.

ENDMETHOD. "process

METHOD endevent.

WRITE: / 'Processing endevent'.

ENDMETHOD. "endevent

ENDCLASS.

*----


*

  • CLASS mainapp DEFINITION *

*----


*

CLASS mainapp DEFINITION.

PUBLIC SECTION.

CLASS-METHODS:

main.

ENDCLASS.

*----


*

  • CLASS mainapp IMPLEMENTATION *

*----


*

CLASS mainapp IMPLEMENTATION.

METHOD main.

DATA:

p89 TYPE REF TO process_execution.

CREATE OBJECT p89.

p89->startevent( ).

p89->getdata( ).

p89->validate( ).

p89->process( ).

p89->endevent( ).

ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

mainapp=>main( ).



Edited by: Matt on Dec 22, 2009 2:03 PM Fixed formatting

Read only

naimesh_patel
Active Contributor
0 Likes
1,104

It goes into endless LOOP because when system executes this statement it carries the new object created in the X_VALIDATOR parameter. So, the object has the reference of its OWN object instead of the SUPER object. This happens because as soon as system executes the statement CREATE OBJECT it creates the object before calling the constructor. SO, when it reaches to constructor it has its OWN object reference instead of the SUPER object reference.


      CREATE OBJECT:
        validator TYPE validation_manager
       ,Validator TYPE validate_format                 EXPORTING x_validator = Validator

From Help:

The CREATE OBJECT statement creates an instance of a class or object and assigns the object reference to the reference variable oref. Directly after the object has been created, the instance constructor of the class is executed.

http://help.sap.com/abapdocu_70/en/ABAPCREATE_OBJECT.htm

So, you need to use the temporary variable to hold the super's reference and pass this variable while instantiating the object.

Regards,

Naimesh Patel

Read only

matt
Active Contributor
0 Likes
1,103

As I mentioned in an email discussion with Benny - there are some seriously talented people in this forum.

Read only

0 Likes
1,103

I am truly honored