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: A mediator for every display item?  (Read 10891 times)
jaxim
Full Member
***
Posts: 22


View Profile Email
« on: April 12, 2010, 12:51:09 »

It is best practice to create a Mediator for every display item/button?

For example, let's say I am creating a music player. Should I create a mediator for the play button, another one for the progress/scrubber bar, another one for the volume button, and so on?
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: April 13, 2010, 06:05:31 »

The short answer is no.

Have a look at the Flex Employee Admin demo. This will give you a good idea about granularity of mediators vs the view hierarchy they are attached to.

Also, for more advice, search these forums for granularity +mediators

-=Cliff>
Logged
dihardja
Jr. Member
**
Posts: 17


View Profile Email
« Reply #2 on: April 14, 2010, 02:06:09 »

Hi,

probably you would have one PlayerMediator for the whole player. You can then handle each event and other players related business logic in separate commands which are executed by the PlayerMediator.   
Logged
jaxim
Full Member
***
Posts: 22


View Profile Email
« Reply #3 on: April 14, 2010, 07:05:54 »

Thanks, Cliff.
I took a look at the Flex Employee Admin demo as you suggested.
http://trac.puremvc.org/Demo_AS3_Flex_EmployeeAdmin

The demo has 3 major view components and 3 Mediators so using this demo as an an example, it would seem that it is best to have a mediator for every major View Component. But I  guess it all depends on what you personally define as "major".

In terms of my music player example, I could have a single mediator if player just was played/paused and adjusted volume. However, to the other extreme, if my player is more robust, I might need more than one mediator. For example,  I may need a mediator for each of these features: play/pause, volume, playlist, progress meter with scrubber, song ID3 data displayer, visualizer, artist slide show, etc. 

Then there is an option somewhere in the middle where I can have a few view components have their own mediators (i.e. a mediator for the playlist component, a mediator for the slideshow component) and I can have a single mediator to control multiple view components (i.e. a mediator for the components:  play/pause button, volume button, and progress meter).

Does that sound about right?

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



View Profile WWW Email
« Reply #4 on: April 14, 2010, 08:29:59 »

One for each 'major' component is usually the case. In the EmployeeAdmin, those are all discrete custom components. And yes, it all depends on what you deem 'major'.

However, to the other extreme, if my player is more robust, I might need more than one mediator. For example,  I may need a mediator for each of these features: play/pause, volume, playlist, progress meter with scrubber, song ID3 data displayer, visualizer, artist slide show, etc. 
Yep. Here you have a pretty huge 'component' it's probably a bunch of components, with different mediators.

Play/pause, volume, and progress meter with scrubber are probably all part of one 'transport' component. I wouldn't want a volume mediator and a play/pause mediator. That would be a bit too granular - for my taste. But this also depends on what you're writing. If you plan to reuse the play/pause component and its mediator in another project (a mini-player perhaps), where the other parts of the transport either weren't there or were radically different, then sure you might actually go down to that granularity because you're going to see some payoff for it.

-=Cliff>
Logged
gohloum
Jr. Member
**
Posts: 16


View Profile Email
« Reply #5 on: July 23, 2010, 02:01:13 »

I'd like to add that your working condition has alot to do with how you would setup your mediators and the entire facade for that matter.  I have the unfortunate displeasure of working at a company where my projects are 'design by committee' with no documentation presented to me, unqualified people making requests for changes and new features whenever they want, etc...  PureMVC has been my code equivalent to LEGOs. 

I have adopted my own custom practice for communication between components and mediators that has been very handy for my situation.  Quite often I start off with a component and mediator pair, but after a Monday meeting, I may come away with over a dozen changes / added features.  It's quite ridiculous. So, as I get to implementing the block outs for the view, I look through the component and see what needs to be it's own component based on what things are similar, and cut that xml and paste it into a new component and setup a new mediator.

So, here is what I do that is specific to my setup that has helped me in this crazy world of flux that I spend 40 hours a week in:

- Components are responsible for creation and destruction of their mediators

This really helps when I use view states and the includeIn or excludeFrom tag for a component (seems to happen alot latey as I think these guys are seeing how far they can push me.
:
// some example code
private function init():void
{
_facade = MainFacade.getInstance(Main.NAME);
_facade.registerMediator(new AdminMediator(this));

}

- Make sure you have proxies for your data.  You wont get very far with the above if you dont - Poof! Gone the minute the state changes...

- Custom payload-able ViewEvent that is dispatched to the mediator from the component.

This is how the component messages it's mediator.  The event has no static constants defined.  It passes constants defined in the component:

:
// defined constants
public static const INSERT_NEW_TESTIMONIAL:String = 'insert_new_testimonial';
public static const EDIT_CURRENT_TESTIMONIAL:String = 'edit_current_testimonial';


// and an example of the dispatch. This one has a payload
dispatchEvent(new ViewEvent(EDIT_CURRENT_TESTIMONIAL, editItem));

Then the mediator has registered listeners in it's constructor
:
public function AdminMediator(viewComponent:Object)
{
super(NAME, viewComponent);
// No references to the facade are allowed in the constructor.
view.addEventListener(AdminView.INSERT_NEW_TESTIMONIAL, viewEventHandler);
view.addEventListener(AdminView.EDIT_CURRENT_TESTIMONIAL, viewEventHandler);
}

and then my viewEventHandler is very similar to the handleNotifications in that it uses a switch statement:

:
private function viewEventHandler(e:ViewEvent):void
{
switch (e.type)
{
case AdminView.INSERT_NEW_TESTIMONIAL:
sendNotification(MainFacade.INSERT_NEW_TESTIMONIAL, e.data);
break;

case AdminView.EDIT_CURRENT_TESTIMONIAL:
sendNotification(MainFacade.EDIT_CURRENT_TESTIMONIAL, e.data);
break;
}
}

As a result, I end up with very consistent mediators in design and refactoring to add a new mediator is quite painless with the help of copy/paste to move over some case conditions and the old find and replace for updating the view names.  And yes, the necessary constants are moved to the new component as well.

Mediator in 5 seconds...

Until some serious support for templates becomes available in FB, I use FlashDevelop to create my actors. It's a little clunky having 2 IDEs open, but it saves time.

If you have FD, you are welcome to my mediator template.  Here is the code below for the fdt file:

:
package $(Package) $(CSLB){
import org.puremvc.as3.multicore.interfaces.IMediator;
import org.puremvc.as3.multicore.interfaces.INotification;
import org.puremvc.as3.multicore.patterns.mediator.Mediator;
import $(Package).*;

/**
* ... PureMVC - Mediator Class Multi core
*
*/
public class $(FileName) extends Mediator implements IMediator
{
// Cannonical name of the Mediator
public static const NAME:String = "$(FileName)";

public function $(FileName)(viewComponent:Object)
{
super(NAME, viewComponent);
// No references to the facade are allowed in the constructor.
}

override public function onRegister () : void
{
// Make any calls to the facade here:
}

override public function getMediatorName():String
{
return $(FileName).NAME;
}
       
override public function listNotificationInterests():Array
{
return [];
}

override public function handleNotification(note:INotification):void
{
switch (note.getName())
{
default:
break;
}
}

/* IMPORT view class and View event
private function viewEventHandler(e:ViewEvent):void
{
switch (e.type)
{
default:
break;
}
}

public function get view(): // add View Class
{
return viewComponent as // add View Class
}
*/
}
}

and here's my view event.  I have a common.events package in my source.
:
package common.events
{
import flash.events.Event;

public class ViewEvent extends Event
{
public var data:Object;

public function ViewEvent(type:String, data:Object=null, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.data = data;
}

override public function clone() : Event
{
return new ViewEvent(this.type, this.data, this.bubbles, this.cancelable);
}


override public function toString():String
{
return formatToString("ViewEvent", "type", "bubbles", "cancelable", "eventPhase", "data");
}
}
}


So yeah... My code is like LEGOs... or should I say Cliff-Blocks?  ;)  I don't know that this would be considered a 'best practice' by any means, but it does allow me to make fairly drastic changes quickly and without bugs popping up provided I moved all the parts that were related to the new components and mediators.

I'd actually be interested to see how others are handling changes in design.... Provided they are plagued with 'Design by Committee' like I am.

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



View Profile WWW Email
« Reply #6 on: July 25, 2010, 01:35:54 »

Sounds like you've adapted well to the environment. I feel your pain, but it's always those pressure-cookers where we learn a lot in a short time. At least there's that. :)

Of course you are coupling your components pretty closely to your mediators, which is not super. You could have an upstream mediator listening for these new components to be added to the stage and registering the appropriate mediator.

-=Cliff>
Logged
gohloum
Jr. Member
**
Posts: 16


View Profile Email
« Reply #7 on: July 26, 2010, 12:34:42 »

Hey Cliff,

Are you suggesting a mediator that listens to the stage for add item events to bubble and then inspecting the targets to see if they are classes requiring mediator construction and wire-up?
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #8 on: July 28, 2010, 01:19:36 »

Yes. Or the Application in Flex / WindowedApplication in AIR. If you have a lot of this, then have that mediator fire off a notification containing the reference to the object that was added, and have a command handle wrapping the mediator around it in a switch/case.

This is a better way than having the view components know their Mediators. It's ok for the PureMVC apparatus to know a lot about the view hierarchy, but it's less good the other way around because then those view components aren't portable without refactoring.

-=Cliff>
Logged
Pages: [1]
Print