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: what is the BEST way to instantiate mediators?  (Read 9961 times)
benissimo
Jr. Member
**
Posts: 13


View Profile WWW Email
« on: June 30, 2011, 06:33:00 »

Hi

first of all thanks to the PureMVC community for providing such a solid framework, I'm really enjoying getting my head round the new concepts.

My question is probably fairly typical, of the form "what's the best place to put code?" but I've taken a good look through the forums and demos and I'm still not clear so I thought I'd just ask for help.

I'll use our real project which is a Video Phone app, although I'm sure the steps are very generic.

So we have a NetConnectionClient object (Proxy) which receives calls from a remote server. One of these is a "doVideoCall" request which means that this client should begin a video call.

on a "doVideoCall" request we want to:
1. create a webcam model to hold all the info for streaming the client webcam, some of which is new and some of which we already have (eg name of this client, width/height of the video)
2. create a webcam view to display the webcam to the screen

here model = Proxy + ProxyVO and view = Mediator + viewComponent

this could be translated into the following simplified code:

var webcam:WebcamProxy = new WebcamProxy( infoObject );
var webcamMediator:WebcamMediator = new WebcamMediator( viewComponent );
var webcamView:WebcamView = new WebcamView( webcam );

just three lines of code, and yet a whole world of possibilities...

I've thought through some of the possibilities so I'll present them as a brief list, with my objection to each one. Maybe someone could point out the best method and why.

Method 1: Use a Command
command acts on a notification from the NetConnectionClient, executes the above code.

Objection: the command doesn't have any knowledge of the stage, so it doesn't have a viewComponent that it can pass to the mediator.

Method 2: Use a StageMediator
stageMediator receives notification from the NetConnectionClient, executes the above code

Objection: the stageMediator is doing all the heavy lifting, will end up with most of code in the stageMediator

Method 3: Separate out creation of Proxy from creation of Mediator
a command creates the WebcamProxy and then fires a notification which the stageMediator catches to instantiate the WebcamMediator

Objection: we have added a notification and a command AND we are still using the stageMediator to create the webcamMediator. ie every request now requires two notifications and a command and must be routed via the stageMediator.

Method 4: Instantiate WebcamMediator on startup
now we can go back to the original command idea since it will not need to instantiate the webcamMediator

Objection: we adopt the practice of registering *all* mediators at startup. Seems like it goes against the principle of only instantiating things at the moment they are needed.

Method 5: Use a StageProxy
now the command can access the stage via the proxy so it is able to instantiate mediators.

Objection: seems a bit weird to create a proxy just so we can get round the problem of mediators requiring a viewComponent when they are instantiated.


I guess if I could distill the above thought process into a single question it would be:

if we want to create a proxy and its corresponding view (plus mediator) and we want all this to happen only at the moment we need it - then what is the best approach for making this happen?

and if I could simplify this question even further it would be:

what is the BEST way to instantiate mediators?

Hence the title of this thread... :)

Any help or further thoughts will be much appreciated!
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: June 30, 2011, 08:38:55 »

Firstly, there is no BEST way, it really depends on when you need a mediator and when its component will be created as to what the logistically correct time for your app is.

Secondly, the mediator does not have to take anything on its constructor and can be registered with no view component. It might be registered and later upon receiving a particular note, create its view component. Of course if it is known that a particular mediator may be registered without a view component then that mediator needs to be aware of this in the way it behaves; i.e. handling or ignoring some notes conditionally based upon existence of the component. It's all up to you.

Thirdly, as you intuited, the idea of the StageProxy is deeply wrong. The main reason is that the Model classes should never know anything about the view, including components, mediators or notes defined for the app. They should send notes defined on the proxies themselves or in a constants file reserved for the model. This ensures the entire model package is portable. Nowadays your model may need to serve different apps for web, mobile, desktop and tablet. So don't ever tie the model to the view. The other way around is fine though. View necessarily depends on Model.

And finally, here's one approach that places the logic in a command where it belongs, and handles the deferred creation of the mediator and component.

> Instantiate the NetConnectionClientProxy in your startup command. In its onRegister, have it connect to the server and begin listening for calls.

> When it gets a call from the server, it sends a NetConnectionClientProxy.START_CALL note. (It should also probably stop listening for calls until such time as this call is over, I'm guessing).

> A StartCallCommand is registered to the NetConnectionClientProxy.START_CALL notification and responds by:

  * Checking to see if the WebCamMediator is already registered and bails if it is.
  * Othewise, it gets the camara from Camara.getCamara(),
  * Creates a Video and attaches the camara to the video.
  * Presumably it is the video you will mediate, so it creates a WebCamVideoMediator passing in the video.
  * Sends off a reference to the video in an AppConstants.ADD_WEBCAM_TO_STAGE notification.
  * A StageMediator is registered, interested in the note and responds by taking the video from the note body and adding it to the stage.

StartCallCommand
:
      if (!facade.hasMediator(WebcamVideoMediator.NAME)
       {

            var camera:Camera = Camera.getCamera();
            
            if (camera != null) {
                video = new Video(camera.width * 2, camera.height * 2);
                video.attachCamera(camera);
                facade.registerMediator(new WebcamVideoMediator( video ) );
            } else {
                sendNotification(AppConstants.DISPLAY_MESSAGE,"You need a camera.");
            }
       }

-=Cliff>

« Last Edit: July 01, 2011, 08:23:17 by puremvc » Logged
benissimo
Jr. Member
**
Posts: 13


View Profile WWW Email
« Reply #2 on: July 01, 2011, 03:34:12 »

thanks for the quick and thorough reply!

maybe I can continue this discussion a step further:

of course I can see there is not a best way to do these things, every project is different and personal taste gets involved too. I've just noticed that (in our project at least) we come across a similar set of steps that need to be carried out:

create and register a proxy
create and register a mediator
instantiate a view

so I wondered if there was a recommended practice for this oft-repeated process. I browsed a few demo projects and didn't see a consistent approach (maybe there's a clue in there).

so if I can comment on the solution you proposed, here's what I notice:
1. commands do the work
2. two (or more) notifications might be usual, the command catches one and sends one
3. use a stageMediator to place concrete view components onto the stage

point 1 I can totally get behind, makes perfect sense

point 2 I can deal with, but it might take a bit of getting used to! I find it hard to follow notifications, when a sendNotification is executed you have to hunt around your source tree looking for the classes that are interested in that notification. I haven't found a system for doing this yet except for "search in files" and that feels wrong!

point 3 I can also understand and will use in this project. I was imagining a future scenario where we had twenty (or more) mediators and twenty corresponding notifications and twenty cases inside a long switch statement in the stageMediator. But maybe I'll find ways round this as the project grows (a generic "place view component on stage" notification?)

Finally, I noticed you created the view object in the command and then passed that into the mediator which is an approach I hadn't thought of. Thanks for that insight! In our case this is especially useful since the mediator can now mediate any video object, including other client streams, making the mediator far more useful. Thanks for that note also!

Looking forward to sharing more with the puremvc community in the coming months :)
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: July 02, 2011, 12:08:09 »

point 2 I can deal with, but it might take a bit of getting used to! I find it hard to follow notifications, when a sendNotification is executed you have to hunt around your source tree looking for the classes that are interested in that notification. I haven't found a system for doing this yet except for "search in files" and that feels wrong!
That's the price of decoupling actors. If everything just retrieved and acted upon other actors, then the IDE could help you click through the relationships, but you'd also have spaghetti code; something decoupling is intended to cure. I do a search across files for notes, and don't really have a problem with it, but you might also look into Kap Labs' PureMVC Console[1] which may help you a bit.

point 3 I can also understand and will use in this project. I was imagining a future scenario where we had twenty (or more) mediators and twenty corresponding notifications and twenty cases inside a long switch statement in the stageMediator. But maybe I'll find ways round this as the project grows (a generic "place view component on stage" notification?)
Sure a generic note would be called for if you're going to be adding a lot of controls via the StageMediator. For instance, ADD_COMPONENT_TO_STAGE notes would do a stage.addChild(component).

But if you needed to add something to a toolbar on the stage, you'd have mediated the toolbar already, and added it to the stage by sending the toolbar in an ADD_COMPONENT_TO_STAGE note. So you'd send an ADD_TO_TOOLBAR note which the ToolbarMediator would hear and do a toolbar.addChild(component). This way is better than having the StageMediator be interested also in ADD_TO_TOOLBAR and doing stage.toolbar.addChild(component). It is more reusable (i.e. you can easily reuse the toolbar and its mediator in another app probably without change), and your StageMediator doesn't have to assume there's a toolbar component on the stage and that it has an addChild method. It knows how to talk to the stage, other mediators can deal with things you put on the stage.

-=Cliff>

[1]http://lab.kapit.fr/display/puremvcconsole/PureMVC+Console
Logged
Pages: [1]
Print