After a while of experience following this approach, considering also your comments here I discarded this approach for me. I leave the original text as it is in order to archive the discussion.
As I promised in my last post, today I come back writing about my experiences with the “use simple types” approach I mentioned there.
The approach
- Avoid references to DDIC types (i.e. structures, data elements, table types) as long as is it is not necessary. A necessity for a DDIC type reference could be:
- A field shows up on the screen (conversion exits and labels are needed)
- You are calling a function module and have to match the types used here
- Use simple, base types for attributes, locals and parameters such as:
- string
- integer
- date
- time
- float
- abap_bool
- string_table (in fact, this is a DDIC type, but it is very basic and very useful when working on arrays)
- Use range of strings in case of the need of selection ranges. Put a type definition for this in some central class of your code base. DB selections will work fine with this
- Use clear, descriptive names for the variables in order to not create confusion about their semantics
Experiences
When I first thought of this, I was afraid, I missed something and the approach could bring more harms than blessings. So I decided to “try it out” for a while.
After having created a number of applications following the approach, I must say that it comes in very handy. I’d like to share some snippets:
methods pbo.
methods set_conf_number
importing in type string.
methods set_work_station
importing in type string.
methods set_test_purpose
importing in type string.
methods set_remarks
importing in type string.
methods exit_command
importing in type string.
methods user_command
importing in type string.
This is part of the declaration of a front end class that communicates with a function group that carries a dynpro. Imagine how easy it was to create those declarations using copy and paste!
The dynpro logic calls those methods on each event that happens on it:
module conf_number_input input.
g_controller->set_conf_number( conv #( zst_pp39_qcheck_strip_screen-conf_number ) ).
endmodule.
module work_station_input input.
g_controller->set_work_station( conv #( zst_pp39_qcheck_strip_screen-work_station ) ).
endmodule.
module test_purpose_input input.
g_controller->set_test_purpose( conv #( zst_pp39_qcheck_strip_screen-test_purpose ) ).
endmodule.
module remarks_input input.
g_controller->set_remarks( conv #( zst_pp39_qcheck_strip_screen-remark ) ).
endmodule.
module exit_0001 input.
g_controller->exit_command( conv #( user_command ) ).
endmodule.
module user_command_0001 input.
g_controller->user_command( conv #( user_command ) ).
endmodule.
Since I am on the front end representation layer here, all my data is typed by referring DDIC. So I have to do a conversion when passing them to my simple-typed class.
private section.
constants function_preview type string value '1'.
constants function_print type string value '2'.
constants info_structure_name type string value `ZST_PP39_CONFIRM_INFO`.
constants work_station_parameter type memoryid value 'ZPP24_WSTAT'.
constants confirm_number_parameter type memoryid value 'RCK'.
constants info_value_width type i value 12.
constants info_description_width type i value 30.
constants (and data) declarations are dominated by simple types. However, some ABAP statements (as for instance get parameter id) require non-string parameters so I had to make some exceptions to my rule.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_PP39_QCHECK_STRIP_BACKEND->FILL_PRINT_DATA
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RESULT TYPE ZST_PP39_QCHECK_STRIP_PRINT
* +--------------------------------------------------------------------------------------</SIGNATURE>
method fill_print_data.
result =
value #(
order_id = |{ order_operation-order_id alpha = out }|
material_number = zcl_ca03_conversions=>matn1_output( order_operation-material_number )
work_center_id = work_center_id
work_center_text = work_center_text
material_description = material_description
test_purpose_text = test_purpose_text
remark = remark ).
endmethod.
This is a mapping method for a communication structure that is used in a smart form. Since the smart form is called via function module, I had to create a DDIC structure for the data that is to be printed. However, the fields of the structures are all simple strings (see below).
Note the conversions I do for the first two fields. For printing, I need the external representation. Here, one could say that using a DDIC field in the communication structure would have done the job of conversion (and I would agree – maybe I will change this).
class ZCL_PP39_QCHECK_STRIP_TYPES definition
public
final abstract
create public .
public section.
types:
begin of ty_order_operation,
conf_number type string,
order_id type string,
activity type string,
material_number type string,
work_center_id type string,
end of ty_order_operation.
This is a class where I declare complex types for use within the application. As you see, the components are all strings.
select single
afvc~rueck as conf_number,
afvc~vornr as activity,
afvc~arbid as work_center_id,
afpo~aufnr as order_id,
afpo~matnr as material_number
from afvc join afko on afko~aufpl = afvc~aufpl
join afpo on afpo~aufnr = afko~aufnr
where afvc~rueck = @in
into corresponding fields of @result.
Here we have a select that fills the structure declared above. Obviously the import parameter in is a string. Using into corresponding fields does the job of converting everything to strings.
data confirm_info type zst_pp39_confirm_info.
This is a structure I use for screen output. Of course, every field in this structure has its DDIC type.
Conclusion
Coding in this way seems more lightweight to me. I like the easy way I can create new parts in my coding doubling a row or region and then changing the essential, while the type references are often identical (referring to a string).
To me, the code remains readable and clean. To understand the purpose of coding logic, normally it is sufficient to understand if I am dealing with a text, a flag or a number. The rest of the semantic comes with clear names.
Original Article:
https://blogs.sap.com/2020/03/25/the-use-simple-types-approach/