Data exchange possibilities in Floorplan Manager

Introduction

The Floorplan Manager (FPM) allows you to separate UI components into distinct building blocks which can be arranged to an entire application. These UI building blocks (UIBBs) may also be reusable in order to use them later on in another scenario. But without exchanging data, only few UIBBs can be properly used. So data sharing between certain UI components is a common requirement, not only in FPM based applications.
There are a lot of good guides in SCN which deal with the question of how data can be exchanged between UIBBs in the FPM.
So initially this blog post wouldn’t be necessary at all and I could have saved my time. The reason why I didn’t, is the fact that none of these blogs deal with the question, what the drawbacks of each approach are and what would be the specific difficulties to deal with in an evolving architecture during the implementation of large enterprise applications.

Options of sharing data between UIBBs

To share data between UIBBs in the FPM, there are mainly three options:

  • Singleton
  • Events
  • Wiring
  • Shared Data component (not usable for Generic UI Building Blocks)

Each of these options will be described below.

The Shared Data Component

Freestyle UIBBs can implement the Webdynpro Component interface IF_FPM_SHARED_DATA. The context of this component can be mapped in any other Freestyle UIBB. Since context mapping is not possible for the Generic UIBBs, I do not further investigate this possibility.

The Singleton-based approach

How does it work

This approach is quite easy to implement. Every UIBB or every OVP-/OIF-/GAF-Exit gets an instance of the application model by calling a static method of the class which implements this application model.

method IF_FPM_GUIBB~INITIALIZE.
mo_application_model = zcl_fpm_demo_application_model=>get_instance( ).
endmethod.

This call will return the same instance at every call. This means, any method and any data will be read from and written to the same instance. This approach is the easiest and one of the more dangerous approaches in terms of maintenance requirements

Advantages

  • Easy to implement
  • Easy to implement also in dynamic scenarios, where UIBBs are registered at runtime
  • Sharing of a single Instance which offers both data and operations to its clients is quite easy, there is no need to share only internal tables or structures which offer no follow-up operations for the UIBBs dealing with these data structures / instead, UIBBs can get an object, retrieve data and also write some data back based on what the UIBBs was intended to do

Drawbacks

  • While in the standard FPM configuration editor, there is no transparency how an UIBB exchanges its data
  • All UIBBs which rely on the application model class will work only with this class, hence, show a strong association with that class. This threats the reusability of that components in scenarios which usually do not deal with this very application model class
  • This issue can be minimized by having multiple singleton instances (application models) which share some data between each other based on generic dependency injections. This could be achieved by using Constructor Injections or Setter Injections of the corresponding application models.
    However, the outcome will be multiple classes whose dependencies would have to be managed separately in an extra FPM component, e.g. the application controller. To resolve dependencies, tools like IoC Container might help – but anyway, you need to be absolutely clear about the application model before starting with a singleton based approach. It is easy to implement at the beginning but might turn out to a maintenance monster if you forget to care about it.
  • Specific UIBBs cannot be adressed conditionally this way. If you do not separately implement some logic which prevents certain UIBBs from getting updates based on the application model, all UIBBS which look for the corresponding model will get and write data from/to it or will not.

The Event-based approach

How does it work

Imagine a Search UIBB which works based on the table SFLIGHT needs to propagate its selection criteria to other UIBBs when the user pressed “Search”. If data exchange was implemented by a Singleton class, the method if_fpm_guibb_search~process_event would try to get the singleton instance and share the selection criteria by calling a method call which might look like this

lo_singleton->SET_FLIGHT_SELECTION_CRITERIA( lt_selopts )

In contrast to sharing the data using a singleton instance, the UIBB could also re-raise the event by actually triggering a new event with event parameters:

METHOD if_fpm_guibb_search~process_event.
...
DATA lo_fpm_parameter TYPE REF TO if_fpm_parameter.
DATA lo_fpm TYPE REF TO if_fpm.
* get FPM
lo_fpm = cl_fpm_factory=>get_instance( ).

* raise apply selection event
lo_fpm_parameter = cl_fpm_parameter=>create_by_lpparam( it_parameter = lt_parameter ).
lo_fpm_parameter->set_value( iv_key = 'SEARCH_CRITERIA_FLIGHTS' iv_value = IT_FPM_SEARCH_CRITERIA ).
lo_fpm->raise_event_by_id(
iv_event_id = 'ON_SEARCH_FLIGHTS'
io_event_data = lo_fpm_parameter ).

...
ENDMETHOD.

Any UIBB which is interested in getting the selection criteria should handle this event in its own PROCESS_EVENT method. Any kind of the OVERRIDE-Methods which are used by certain exits are also welcome.

DATA: lr_data TYPE REF TO data.
CASE io_tabbed->mo_event->mv_event_id.
WHEN 'ON_SEARCH_FLIGHTS'.
FIELD-SYMBOLS <lt_selopts> TYPE FPMGB_T_SEARCH_CRITERIA.

io_tabbed->mo_event->mo_event_data->get_value(
EXPORTING iv_key = 'SEARCH_CRITERIA_FLIGHTS'
IMPORTING er_value = lr_data ).
ASSIGN lr_data->* TO <lt_selopts>.
...
ENDCASE.

Advantages

  • Easy to implement
  • Easy to implement also in dynamic scenarios, where UIBBs are registered at runtime
  • No extra class for the backend object needed

Drawbacks

  • No transparency while in the configuration editor, how an UIBB exchanges its data
  • Danger of creating endless loops caused by cascading event raisings without having a chance of knowing it when in a certain feeder class. Example: This could happen if UIBB 1 triggers an event which is handled by UIBB 2. UIBB 2 in triggers another event itself which is handled by UIBB 3. This component could also trigger its own events, which could eventually cause UIBB 1 to start the event loop again.
  • only visible UIBB take part in the event loop, invisible UIBBS (e.g. in other tabs than the currently selected tab) do not receive the data
  • You cannot address specific UIBBs this way, instead all visible UIBBS take part in the event loop and will handle this event or ignore it
  • The parameter signature of the events might change without notice, or worse, another UIBB which raises the same event uses the same parameters but with another type. This ain’t fun for the clients of these events

The Wiring-based approach

How does it work

Wiring is the standard FPM-concept to share data. I’m not going to explain it here. Instead I refer to help.sap.com, the FPM developer guide, or the official book
There are also guides in SCN which describe wiring based on structures or tables.

Advantages

  • Since the connector classes and the data which they provide are defined at design time and used both on sender and receiver side, surprises are less certain than in the event-based approach. However, a sender might still decide to return different data via its outports which will cause an error at runtime
  • This little disadvantage brings us to the next advantage: Wiring can be configured in the FPM configuration editor. Errors can be found much quicker since every data exchange needs to be registered here
  • This also makes transparent, which data the UIBB you are currently configuring, really uses

Drawbacks

  • It is very difficult to implement wiring in dynamic scenarios, where UIBBs are added at runtime
  • This drawback is not mentioned because of the wiring concept, rather because of the way it is commonly used: Developers tend to share structures and tables between UIBBs without the possibility to support follow-up operations since these still remain simple data objects, but no object instances. Sharing application models between UIBBs is a much more powerful possibility which I might demonstrate in an upcoming blog
  • Compared to the other options it is the most complicated approach and might be hard to follow and implement for someone who is new to FPM development

Conclusion

Every approach has its specific advantages. What we learned in real implementation projects, is, that there is always a mixture of these approaches depending on the scenario and the requirements in terms of reusability of UIBBs. If your UIBBs need to be reusable in various scenarios the approaches to exchange data should be (in order of relevance): Wiring before Singleton before Events.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s