Abstraction & Inheritance in WD-ABAP Clones of CL_WDR_ALL_IN_ONE_UTIL/UIELEM: What’s a lazy wannabe to do?
In a couple of previous posts, I mentioned how one can use the WD-ABAP component WDR_TEST_UI_ELEMENTS to create one’s own tutorials for many different view models.
But since I am in general a lazy wanna-be who has never had the courage to write any piece of code from scratch, I started looking yesterday at the WDR_TEST_UI_ELEMENTS component in order to learn two more general techniques – how to fire a tree view from a selected link in a tray, and how to fire a detail view from a selected tree element.
And in the process of learning the answers to these two questions, I found out that in order to use what I’d learned “for real”, I needed to make a decision on abstraction/inheritance that I really didn’t trust myself to make. So the purpose of this post is to ask the SDN community for its opinions on this basic question of abstraction/inheritance. I apologize for the long preamble to this question that appears below, but in order to understand the question, you really have to understand exactly how WDR_TEST_UI_ELEMENTS draws on the methods and attributes of the two classes CL_WDR_ALL_IN_ONE_UTIL and CL_WDR_ALL_IN_ONE_UIELEM.
add it to the hierarchy tree
=> create the sub node and add an element to it
lr_hier_tree_context_node = m_hier_tree_context_element->get_child_node( ‘UI_ELEMENT_HIER_REC’ ).
lr_hier_tree_context_element = lr_hier_tree_context_node->create_element( ).
lr_hier_tree_context_node->bind_element( new_item = lr_hier_tree_context_element set_initial_elements = abap_false ).
lr_hier_tree_context_element->set_attribute( name = ‘EXPANDED’ value = abap_false ).
lr_hier_tree_context_element->set_attribute( name = ‘HAS_CHILDREN’ value = abap_false ).
lr_hier_tree_context_element->set_attribute( name = ‘TEXT’ value = i_aggregatee-display_name ).
concatenate ‘/sap/public/bc/webdynpro/viewdesigner/icons/’ i_aggregatee-display_name ‘.gif’ into icon.
lr_hier_tree_context_element->set_attribute( name = ‘ICON’ value = icon ).
OK – so now we know what old-timers would call the “flow of control” that builds the aggregation tree on the right hand side of the Main view, given the selection of any link in a tray on the left-hand side of the view.
But where is the data itself coming from – the data itself that is used in the methods create_aggregations and create_aggregatee? And how do these methods get the data?
The answer is in the wdDoInit method of the Main view of WDR_TEST_UI_ELEMENTS itself:
method wdDoInit .
implicit available data objects
wd_Context type ref to if_wd_context_node.
wd_This type ref to if_Main.
create an instance of the handler class
create object wd_this->m_handler.
Since m_handler has been declared in the attributes of the Main view to be of type cl_wdr_all_in_one_util, this create statement must take us to the constructor method of this class:
initialize the meta data
And lo and behold, this constructor method transfers flow of control to the init_meta_data method of cl_wdr_all_in_one_uielem (NOTE! NOT cl_wdr_all_in_one_util), which is where the actual data is created and stored in itabs that will persist sufficiently long to be accessed in the create_aggregations and create_aggregatee methods of cl_wdr_all_in_one_util:
get all libraries
select * from wdy_ui_library into table mt_ui_library
order by primary key.
get all view elements – below we will build the final list
select * from wdy_ui_elem_def into table mt_ui_elem_def_all.
(Note that the itabs mt_ui_elem_def_all and mt_ui_library are TYPED in the attributes declaration of cl_wdr_all_in_one_uielem.)
So now that we have learned exactly how the WD-ABAP component WDR_TEST_UI_ELEMENTS populates the aggregation tree on the right from a selection on the left, we have learned a general way to fire any tree from any link within a tray of any set of trays: we get the back-end data we need in the constructor method of a class like cl_wdr_all_in_one_uielem, and display this back-end data using methods like create_aggregration and create_aggregatee in a class like cl_wdr_all_in_one_utils. For the sake of discussion, call these zcl_back_end_data and zcl_displayed_data,
But – we have now reached the point of this post: how generic and abstact should our class zcl_back_end_data be?
Remember – the code itself is sufficiently general to permit any tree to be built from data in two custom tables that are the equivalent of the wdy_ui_library and wdy_ui_elem_def tables declared in the attributes section of cl_wdr_all_in_one_uielem.
So, do we want:
1) one zcl_back_end_data class with different selects that fire based on a parm passed in during the init of a particular view;
2) one zcl_back_end_data class that leaves it to subclasses to say which selects fire against which tables?
3) multiple zcl_back_end_data class’s that each get data from appropriate tables?
I would very much, therefore, appreciate any input from knowledgeable SDN folk about which of the alternatives (1-3) they would choose. I am sure there are many who deal/have dealt with this kind of question on a daily basis and can render good advice, and I’m hoping their answers will all pretty much say – “it all depends” (because that’s the kind of answers you learn the most from.)
So, thanks for any time anyone can afford to spend thinking about the above question and putting their thoughts into a reply.
PS: if you drill-down from the onactionon_select_view_elem of the Main view of WDR_TEST_UI_ELEMENTS, you’ll learn exactly how the detail view is fired from selection of a tree node in the aggregation tree on the right, but you’ll also again see that you again wind up in methods of CL_WDR_ALL_IN_ONE_UTIL that rely on back-end data gathered via cl_wdr_all_in_one_uielem=>init_meta_data( ).