Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: Pipes, Fabrication - Excessive?  (Read 7000 times)
Justin
Full Member
***
Posts: 24


View Profile Email
« on: April 20, 2009, 01:52:33 »

I am intimately familiar with the multiCore version and the Pipes utility since it was used on a lengthy 6 month project that I was part of.  The more experience I received with Pipes, the more cumbersome and cyclical it seemed because of the 4+ steps involved in achieving communication between 2+ modules.  Also, as the scope of the project grew, so did the number of Message-to-Notification conversions.  In the flex profiler, Notifications from one module to the other were taking anywhere from 50-150ms to get to their destinations.  Now, a utility based on it (Fabrication) seems to further exacerbate the obscurity of module-to-module communication and presumably sharpens the learning curve for those new to PureMVC. 

The code is absolutely beautiful in both utilities and they both offer some interesting benefits but there is a more direct, a faster, and an easier way that compresses the job of module-to-module, module-to-shell, and shell-to-module communication into a single method.  Its so simple, I am convinced that I am missing something but I just don't see it.  Can someone help?

Here is the method and it can be placed on any subclass of the Facade that wishes to perform module to module communication:

:
public function broadcast(name : String, body : Object = null, type : String = null, destinations : Array = null) : void
{
// Assume all modules will receive the notification, even the calling Facade instance.
if (!destinations)
{
for (var key : String in instanceMap)
Facade(instanceMap[key]).sendNotification(name, body, type);
}
else
{
while(destinations.length)
{
try
{
Facade(instanceMap[destinations.pop()]).sendNotification(name, body, type);
}
catch(e : ReferenceError){}
}
}
}

All this does is take an array of keys that were assigned to the Facade instances on creation and matches them in the instanceMap to route notifications.  All you have to do is call braodcast() (Global) instead of sendNotification() (Local) when you want to notify other modules. Targeting occurs by passing the array of keys to the method.  Since the static instanceMap already contains the instances of any and all Facade objects created within the application (provided the getInstance() factory method is used), it seems silly to do it any other way...unless of course I am missing something.

Justin
« Last Edit: April 20, 2009, 02:30:10 by Justin » Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: April 21, 2009, 05:56:36 »

The main reason for using messages instead of notifications in pipes is that you cannot assume that you know or control the registered notification names in the destination module. Imagine a third party writing widgets for your app or visa versa. Retrieving another facade, and manipulating it in this way breaks the encapsulation of the module.

Messages and their names, placed in a shared library gives you a protocol, a common ground to communicate. You could place notification constants in a shared library, but your note body is still just an untyped object, so you can't count on the contents. By subclassing message and passing it you have a strongly typed payload. And sure you could sublcass notification, but then you loose the use of the sendNotification convenience method and have to use facade.notifyObservers everywhere.

Believe me, I went round and round and round again on this because I did MultiCore explicitly for a client whose ultimate goal is to have third parties developing modules for their system (http://ahead.com).

Pipes / Messages was the best solution I could arrive at that protected the encapsulation of the modules to an extent that allows for these conditions. BTW, later this year, Ahead will be releasing their patented framework which I built atop MultiCore to solve the problems Fabrication is going for. It abstracts ALL the plumbing to a matter of subclassing the appropriate Module type (there are 3 roles for modules App, Widget, and Adapter), and simply writing a configuration file for deployment into the desktop or web client container which you see in an early beta form on their site right now. And we have a standalone AIR client that keeps you from even having to write the app.

-=Cliff>
« Last Edit: January 18, 2010, 04:24:43 by puremvc » Logged
Justin
Full Member
***
Posts: 24


View Profile Email
« Reply #2 on: April 21, 2009, 10:09:22 »

The main reason I took a closer look at Pipes and an alternative was because I found myself writing huge ShellJunctionMediators and ShellMediators just to handle the volume of notifications that needed to be redistributed to each of the loaded modules.  Often times the shell could care less about the notification or message since the bulk of the logic is in the modules.

The chain of events seemed excessive; from the module, an event was dispatched by a control, picked up by the module's mediator, converted to a notification that was picked up on its JunctionMediator, a pipe message was sent from there and picked up on the shell's JunctionMediator, then in went round again to each module as a pipe message where it had to be converted to a notification which was picked up on the mediator and finally acted upon as necessary.

Profiling the execution times gave me values at 50-150ms for Notifications to reach their destinations and longer if I factored the PipeMessages into the equation.  Lots of array iterations and switch cases to go through.  Cumulative array instances from listNotificationInterests where in the thousands after just 5 minutes of usage in this particular test.

Type checking can/should be done at the receiving end anyway for notifications, module or not.  Here is a thought, notification names are registered to the Controller via registerCommand(), why not register the notification body type in a similar manor?  e.g. registerNotificationType(notificationName, typeClassName).  Notification names must exist in the registry with an associated type before they are valid.  Sending a notification with a mismatched body type results in a failure prior to the creation of the Notification Object.  This seems like it would solve that problem with a lot less work and remove the ambiguity from notification body in all instances, multiCore or not.

What are your thoughts?

Justin
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: April 21, 2009, 03:33:27 »

Sounds like you might not have explored alternative plumbing schemes. If Module A and Module B need to communicate but the Shell never cares, then simply plumb Module A to Module B and visa versa and be done with it. You might use a command in the Shell to do that initial plumbing, but subsequently, you don't need every message to bounce through the Shell.

Regarding the registration of types, it seems attractive, but it would A) break compatibility with prior versions and B) defeat the purpose of having an easy way to toss things around in the app without strong typing. I did that because I thought of all the times I'd love to send arbitrary data with an event but not have to write a custom Event class to do it. If I want to send an array of data I'd have to go register that, but then later it might become a VO and then I'd have to go and register the type as a VO. Still having to cast when I catch it anyway.

-=Cliff>
« Last Edit: April 21, 2009, 04:25:35 by puremvc » Logged
Justin
Full Member
***
Posts: 24


View Profile Email
« Reply #4 on: April 21, 2009, 09:09:24 »

After posting this last one, I thought how I might be wasting your time.  It's silly to think that such a simple and trivial adjustment to the architecture could have a remote possibility of replacing Pipes which was very well thought through by an incredibly experienced programmer prior to it's release.

The problem with plumbing Module A to Module B is that Module B may or may not exist in every case.  Also, any 2 combinations of 5 total modules are active at any given time and the only common denominator is the shell.  The shell has the responsibility of loading and destroying the modules so the safest approach was to route everything through the shell.

Besides, Module to Module plumbing wasn't in the examples and Pipes are the damnedest thing to catch on to when you have a hard and fast deadline.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #5 on: April 22, 2009, 04:16:51 »

Hey you never know when some totally obvious thing will have been overlooked, so it is always better to suggest than not. But I definitely cranked on this particular Rubicks cube for a while. :)

In the Ahead Framework, everything is configured up front including what does what and how many of each module to preinstance and keep in a cache if any.

So for instance, An App module might be plumbed to an Adapter module instance and first orfer of biz for the App is to tell the Adapter to fetch a Flicker set, say. It hets back a list of 20 images, so only then does it know how many image thumbnail/selector widgets it needs. For each image in the set it sends the shell a request to plumb one of these widgets, using the id of the image as a pipename. The shell grabs a widget from cache (or creates a new one if cache is dry) and then plumbs the widget to the app and sends the app a message saying that pipe is in place. Now the app can talk directly to the widget and visaversa from here out.

-=Cliff>
« Last Edit: January 18, 2010, 04:25:03 by puremvc » Logged
conrad
Jr. Member
**
Posts: 10


View Profile Email
« Reply #6 on: January 18, 2010, 11:26:43 »

I've come up with a new appraoach that I would like if people had a look at - It's decoupled but doesn't need pipes etc...

Have a a look at

http://forums.puremvc.org/index.php?topic=1611.0

and see what you think.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #7 on: January 18, 2010, 04:26:23 »

You can now find out a little more about the Ahead framework and sign up for the upcoming beta at http://imajn.net

-=Cliff>
Logged
Pages: [1]
Print