PureMVC Architects Lounge

PureMVC Manifold => MultiCore Version => Topic started by: darnpunk on August 19, 2009, 11:32:49

Title: One proxy for all modules
Post by: darnpunk on August 19, 2009, 11:32:49

Is there a way to have one proxy accessed directly by different modules. Currently, I have a few modules and they access each other proxies through pipes. I am wondering if there are any utilities where I can have one general proxy to sit in a particular module and have the rest of the modules access this proxy directly so that I do not have to go through the pipes?


Title: Re: One proxy for all modules
Post by: puremvc on August 20, 2009, 04:21:23
The short answer is don't do that. Modules should mainly share data formats and message protocols not references to internal business actors. Modules often share interface implementing view components, often manufactured by one module and inserted into the display hierarchy of another. But they typically do so by shared interface, and not by knowing the implementation class.

Here is my response to a similar question that was posted on the linked in groups recently:

The concept of sharing 'Global' business actors is at odds with a modular system. While it may be true that certain information may be needed by some or all of the modules in an application, it does not mean that those modules must be able to have direct references to the actors responsible for managing that data.

Modularity in software is meant to reduce the code dependencies between modules *as much as possible*. All that is *actually* required for the modules to share information is the data and some protocol for requesting it be retrieved or updated.

If all modules are going to share a reference to a business actor (i.e. the 'global' Proxy ), then all of the modules must share a reference to that class *in addition to* the class that carries the data (i.e. a value object). Sharing a global Proxy means if that Proxy is refactored, all of the calls that are made to it in various modules must also be refactored. And shared actors tend to become bloated as each module's requirements cause more and more 'convenience methods' to that actor

With MultiCore and Pipes, the fact that you can't just retrieve the Proxy and make a method call is both a curse and a blessing. It means focusing on creating the protocol for messaging between the module that needs the data and the module that is responsible for maintaining it. And making sure the modules are plumbed appropriately.

In a simple setup you might build a ServiceModule that has the Proxies needed, an output pipe tee-split out to all your other modules and an input from the Shell.

When the Shell has instantiated all the initial modules, it could then send a message to the ServiceModule, whose various Proxies would generate and/or make service calls to fetch initial data and send the data off to the output pipe where it'd be copied out to all modules.

You can pass the value object(s) on the message(s) from the ServiceModule and in the other modules, pluck the value object from the message and do whatever you want to with it.

If your module needs to cache that 'global' value object so it can refer to it locally as need be, you don't have to have a reference to the GlobalDataProxy class that tends it AND knows how to call the service or generate the object.

All you have to do when your module receives its reference to the global value object is register a local instance of the PureMVC framework Proxy class. No need to subclass it, just give it the value object as its data and supply a name for it on the constructor:

facade.registerProxy(new Proxy("GlobalData", globalDataVO));

Now any Command, Mediator or Proxy, in that module may simply do:

var globalVO:GlobalDataVO = facade.retriveProxy("GlobalData").getData() as GlobalDataVO;

Make the GlobalDataVO a Bindable class, and remember that all modules have the *same reference*, the one held by the GlobalDataProxy in the ServiceModule. Say this VO is bound into a dashboard component, which exposes all its data. If one of the properties is changed by any module they'll all be updated visually. If the ServiceModule recieves a server push and this data is updated, all the others will recieve the changes.

Make modules share Messaging classes for agreeing on a protocol and Value Object classes for agreeing on the data model. That's the way to reduce coding dependencies in a modular system. As long as a group of modules speak the same protocol and understand the data being shared, they can collaborate to solve any task.


Title: Re: One proxy for all modules
Post by: Jason MacDonald on August 21, 2009, 09:32:44
Make the GlobalDataVO a Bindable class, and remember that all modules have the *same reference*, the one held by the GlobalDataProxy in the ServiceModule.

Just to play devil's advocate for a min; I thought this was considered a big no-no since it only applies to Flex? Wouldn't this require putting a [Bindable] statement into a Proxy class?

Title: Re: One proxy for all modules
Post by: puremvc on August 24, 2009, 10:36:00
Nope. No need for bindable in the Proxy. You can add Bindable to the VO and all its properties will be bindable. So the recipient of the VO can populate a combo with these VOs, say, and then if the data in those VOs change, then the combo will be updated.

This is only available in Flex, true. If you're writing a Flex app, take advantage of features on the ground today, but don't let them force you to write things in such a away that would force major architectural rethinks in the future. If you want to eschew binding, and write more complete proxies that send notifications every time something changes, you can. That means if you port to, say Java, you'll've done the hard work and it won't have to be rethought.

But you can get away with a lot in Flex by passing bindable objects around and plugging them into controls. If you're using Flex, it would be silly to write code that does the same thing binding does just to be 100% portable today. Later if you go to Java, and don't have binding available, you can fill out the proxies then, and all the actors remain the same.


Title: Re: One proxy for all modules
Post by: Orion on November 05, 2009, 05:03:36
Another question: how I can create and connect new pipe within module?

I have shell with some Proxies - CarProxy, DriverProxy and TownProxy and 3 types of modules: BigModule, SmallModule, NonVisualModule. Not all Proxies needed in each module. For each Proxy I create different pipe (Proxy generate notification, and different notification sended with different pipes).

BigModule use all my pipes, SmallModule use one and NonVisualModule use no one pipe. All module have one super class StandartModule, and I use this Class in ShellJunctionMediator when I create and connect pipe between each module and shell. If I connect all pipes to all module, handlePipeMessage executed all, times when I send message.
I want send message to module who needed CarProxy, but this message receive all my modules (executed all handlePipeMessage() in modules also in NonVisualModule).

I see some way to solve this problem:
1) Override JunctionMediator.ACCEPT_INPUT_PIPE, JunctionMediator.ACCEPT_OUTPUT_PIPE in module.
2) Create special property in StandartModule "neededPopes" and check this property in ShellJunctionMediator.
3) Connect pipes not in ShellJunctionMediator, but in ModuleJunctionMediator(I dont know how, because in module I cant see shell).

Title: Re: One proxy for all modules
Post by: puremvc on November 05, 2009, 09:44:31
A module cannot create a pipe to another module it doesn't have a reference to. The plumber must have access to both modules in order to connect a pipe between the two