I’m a long time ABAP’er (amongst other things) who also got involved in Web Dynpro for JAVA early on. There were a few interesting features and stability issues in the past, but the whole approach for WD4J was pretty straightforward and aligned to MVC pretty well.
However, when it came to transferring my understanding of WD4J to WD4A, I was a little confused at first as the Window Controller and assistance class threw me. I had previously developed quite a few smaller WD4A apps, however, recently I had the chance to developer a larger scale development which required component development and leveraging all the features of Web Dynpro and came away with a few thoughts around how MVC is established and potentially a pattern for building WD4A applications.
First for the observations:
- The Assistance Class seems to be a much better global data storage location than the context or local variables withina controller (assuming they don’t need to be mapped through a context). Not to mention, the performance is supposedly much better (according to SAP help)
- The Window Controller seems to own things much more than the Component Controller making me wonder whether the Component Controller could just be wrapped into the Window Controller. i.e. The Component Controller can’t navigate; but it can tell the window controller to navigate. All the Component Controller seems good for is interfacing and Context Definitions.
- It’s funny how the Window inbound plug hides its parameters (that would be passed via the URL) within the code section where on all other plugs on views, it’s there in the definition screen (that one hurt me one day).
- All the tutorials out there have views navigating to other views which from an MVC pattern seems strange unless you want to throw the View Controller in as a real controller (I don’t typically) –To get around this, the Component Controller can tell the Window Controller to fire plugs provided you include it as a reference in the Component Controller.
- It’s kind of annoying that if you want to reuse one interfacing component in another component multiple times, that the node structure can’t really be more than 1 deep as otherwise you need to map to new nodes within the Component Controller. i.e. The underlying code makes the Node Name specific, henceif you had NODE1 and NODE2 and mapped an interface node to each NODE but the node you were mapping had child nodes; you would need to map these separately (or something like this).
- WDDOINIT of the component controller is correctly called prior to the Window DEFAULT plug, but this means if you have parameters passed within a URL; you cannot initialise much in WDDOINIT. (solution is to call an initialise method from the default plug on the Component Controller)
So what’s this all about MVC…
Well my understanding of MVC is that the Model is separate from the View, and the controller controls what data is retrieved from the Model plus what view to display and what model data to pass to the View.
So first I was thrown by the fact that WDDoInit is called without any application context information except sy-uname that’s running the application (as per my last point above). So this got me to thinking…For a component that is not going to be interfacing to another component, the Window Controller is actually more powerful than the Component Controller. Now because I have the WD4J background,I’m going to assume that I’ve missed the point somewhere, and I’m still going to focus on the Component Controller being my main controller.
Unfortunately, from an MVC perspective, the controller is more than what the Component Controller can do as I cannot navigate directly from it to a different View. I could fire an event and asynchronously tell a view to fire a plug (which is not a good idea); pass parameters back from methods called by the View (also not great) or I could call a method on the Window Controller to fire a plug.
If I do the latter, I would consider the Component Controller and Window Controller as one (A perfect match made in Waldorf).
So what does this look like:
WDDOINIT of Component Controller – Initialises anything global looking that requires initialisation.
Start plug of Windows Controller – This calls method on the Component Controller to initialise the model data and navigate appropriately.
All navigation gets initiated by the Component Controller by calling an appropriately defined Window Controller which fires it’s own outbound plug to change views. Note – There will be exceptions to this especially if you just want a basic navigation from one view to another like in a tab control or something but in this scenario, I would consider the View Controller as a mini controller quite capable of performing these types of tasks.
Main context is all stored in the Component Controller. The Window Controller just handles navigation and entry points to the application.
Anyway, that’s the gist of it. I’m really hoping for someone from SAP (Thomas perhaps – hint hint – Congratulations on the birth of Ryan Thomas Jung again) to conduct a “best practice patterns” style presentation covering the best “typical” approach to things like larger WD4A applications, but this is my short version of it for now that I’d love to hear from others how they maintain the MVC pattern within WD4A.
Thanks all who got this far and hopefully see you at SDN Day in Brisbane next month or at Tech Ed Phoenix.