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

Show Posts

* | |

  Show Posts
Pages: 1 [2] 3 4 ... 6
16  Announcements and General Discussion / Getting Started / What is the recommended number of notifications for a command? on: June 20, 2011, 09:04:24
Quite by accident, I found this in our code base:

:
public class AppStartupCommand extends SimpleCommand implements ICommand {
  ...
  override public function execute(notification:INotification):void{
    switch (notification.getName()) {
      case ApplicationConstants.START_UP: {
        //40 lines
      }
      case ApplicationConstants.LOAD_CONF: {
        //5 lines
      }
      //approximately 100 more lines of case statements, approx 10 case statements total
      //mostly registering mediators, proxies, and other commands
    }
  }
  ...
  //subroutines... so that no case statement goes beyond more than a few lines
}

At first I was kinda horrified... case statements in execute() ?!  But then I remembered that I had considered doing this myself in the past.

Is there any good rule of thumb for how to decide when multiple notifications should share the same command as above, and when a notification should have its own command?  I am about to recommend to this person that they implement a separate command per notification since there is no single piece of shared logic in any case statement (ie: nowhere do case 1: ... case n: call a common sub-routine).  But on the other hand, the entire class file is only 350 lines long, and there are no other command classes cluttering the code base... and the code is sequential.  I'm just worried about it getting out of hand.  I don't want to see a project later where every notification goes through one monolithic command.  Honestly, I have always had just one notification per command.  Any logic that couldn't handle a given structure of body data needed another command/notification.

I have to admit, though, at its current scale, his method was also a lot easier to implement than using the Loadup utility.  (basing this assumption on the amount of time he spent coding this versus the amount of time I spent struggling to comprehend Loadup tutorials).
17  Announcements and General Discussion / Getting Started / Re: Best practice for using the type parameter with multiple-instance Mediators on: June 20, 2011, 07:42:07
Thanks for the reply, Cliff.  Your second assumption is correct, there are no notes that all instances will respond to.

However, *currently* the view component instances are created in the mediator's onRegister() method.  This is just to defer instantiation and speed up application start time.  Please tell me if this violates convention--I've been doing it for some time.  Also, the data sets to be used in the application are determined from a separate initial query so the number of View/ControlPanel pairs is dynamic.

:
//very simplified...
for (var i:int = 0; i < dataConfig.length; i++) {
  ...
  facade.registerMediator(new ViewMediator());
  facade.registerMediator(new ControlPanelMediator());
  ...
}

I *could* modify the application so that it instantiates the view components first, sets the type parameter on them, and then passes them to the mediator constructor during the start-up.  It would just be some work changing the current code (but not a problem).  However I am a bit reluctant on principle.  The type value is of no consequence to the view component.  I would essentially be putting it there for the benefit of its mediator which seems... odd.  The view component would never actually use the type variable itself.

Anyway, you did make me think of something new with your suggestion.  Until now, I have been pretty strict about not modifying the constructor arguments with the framework classes.  I guess I thought that was best practice.  But if mediator constructor arguments may be arranged, added, deleted, etc. freely, then how about I pass the type argument there directly? 

:
facade.registerMediator(new ViewMediator(dataId));
...
public function ViewMediator(dataId:String)
{
    sharedType = dataId;
    super(getMediatorName());
}
override public function onRegister():void {
  viewComponent = new View();
}

Is there a best practice regarding framework class constructors?  Or a convention?  There have been times in the past that I wanted to pass parameters to the mediator through a third constructor argument but have not done this because I thought it violated convention (which is to say I haven't seen it done anywhere else).  In those instances I have unhappily dispatched notifications to set properties on the mediator. *1

Don't get me wrong, depending on your response, I may still go ahead and just add the type variable to the view components with a comment stating "Used by mediator.  Not junk.  Do not delete."  But in a way, I don't see much difference between this:

:
  var view = new View();
  view.sharedType = type;
  var med:ViewMediator = new ViewMediator(view);
  facade.registerMediator(med);

and this:

:
  var view = new View();
  var med:ViewMediator = new ViewMediator(view);
  med.sharedType = type;
  facade.registerMediator(med);

except that I know we have discussed not exposing properties or methods on the mediator.  If this risks just becoming a debate about "worse is better" let's leave it at that.  I don't need to waste your time.  I intend to follow your ultimate recommendation regardless.  But if the issues I raised would affect your recommendation, then I hope you will share your thoughts.  If not, I am just going to proceed with your first suggestion.

Thanks again for any feedback.

*1 There is a reason I have become militant about the mediator constructor being limited to (name, viewComponent).  That is because I have had people put all kinds of crap in there, including a second view component (remember, view/control panel pair).  Fed up with this, I made it a rule that the constructor is never to deviate from: (name=NAME, viewComponent=null).
18  Announcements and General Discussion / Getting Started / Best practice for using the type parameter with multiple-instance Mediators on: June 20, 2011, 02:42:20
Ok, first, I have a way to do this, but I want to see if this is really the best way to do things.

I have two types of mediator classes.  One is a generic view, the other is a generic control panel.  Each view/control panel acts as a pair.  These pairs have the exact same function except that the data they work with is different in each case.

Because of this, I have implemented just two classes: ViewMediator and ControlPanelMediator.  The application as a whole displays data sets A, B, and C.  I have instantiated my view/control panel pairs with names like: "ViewMediatorName/A" and "ControlPanelMediatorName/A".

Now the hard part is for a given ControlPanelMediator to affect a given ViewMediator I need to use the type parameter to make sure unrelated actors of the same class aren't also effected.  In other words, ControlPanelMediator/A needs to control ViewMediatorName/A (for example, telling it which attributes in the common data model to display, whether to be transparent or not, etc.).

Currently, I am having these two mediators extract a "sharedType" variable from their names upon registration. 

:
override public function onRegister():void {
  //mediatorName = "ViewMediatorName/A"
  //sharedType = "A";
  //same thing for ControlPanelMediator
  sharedType = mediatorName.split("/")[1];
}

Then when ControlPanelMediator sends a notification, it sets the notification type to this variable, and the ViewMediator with the same sharedType variable handles the notification (all other ViewMediators ignore it).  I think that part is relatively sound.  But it's the actual method of extrapolating this "sharedType" variable from the mediator name upon registration that I am unsure about.

Is this the best way to do this?  I was thinking I ought to explicitly set the "sharedType" on each mediator... but how would I do that without making a big mess?

Remember, the point is I don't want to subclass these for each data set used in the application because the data sets are identical in structure.
19  Announcements and General Discussion / Getting Started / Re: Why should I bother to register my Proxy classes? on: May 29, 2011, 08:44:51
Cliff, thanks for your thoughts.

BTW:

I never advocated making Proxies into Singletons.

I know you weren't actually advocating Singletons... but anyway the point about the Model already being a Singleton registry I think is great.  I hadn't ever thought about that before.

You've saved a whole line of code this way, surely that's a big win for the team somehow.

Thank you for that.  That's the laugh I needed on this Monday.  (our code base is totally full of win... that's the "w" in "wtf")
20  Announcements and General Discussion / Getting Started / Re: Why should I bother to register my Proxy classes? on: May 25, 2011, 06:33:49
Hi Cliff,
Yes, by global I meant that it is defined outside the function in the class bracket itself.
It was declared as is (no access keyword), which I believe means it is internal or private. 
So please read:

:
private var _proxy:MyProxy = new MyProxy();
The Mediator is instantiated once in the application and no other part of the framework accesses this proxy instance.

So allow me to play the devil's advocate and preemptively argue with you (because I will no doubt have this argument myself, and I don't want to start it until I am sure I will win).

1) So that more than one actor can retrieve it.
No other actor will need this.  The data this proxy retrieves is for this Mediator.  It's in the docs.

2) So that you can ensure there's only one instance of it in use within the app (if need be) without having to implement it as a Singleton.
Ok, we used to make these Singletons until you told us to stop doing it.  So shall we go back to making our Proxies be Singletons?

3) For the life cycle benefits of registration with the Model. When the Proxy is registered, it's onRegister method is called. This gives you a common place to set up your services and add listeners. When the Proxy is removed from the Model, onRemove is called, giving you the opportunity to remove those listeners and do any other teardown to ensure its availability for garbage collection.
This is very esoteric.  But for this particular case, the actual listeners for the URLLoader are inside the Proxy itself so I don't see any problem.  We have to use the same due diligence here as we do when registering listeners inside of view components.  Those don't have any onRemove().  Furthermore, when have we ever unregistered a Proxy?  Why would we ever unregister any Proxy?  Anyway, esoteric as it is, this argument might be persuasive under other circumstances, but why all the trouble for this little URLLoader Proxy?

4) Because if another actor needs this Proxy, they'll have to instantiate it as well (thus duplicating resources and not having access to the other instance's data), or ask this mediator for it, which is way outside the scope of the Mediator's responsibilities.
Again, no other actor will ever need this Proxy.  It's in the documentation.  The requirements are not going to change.  In the unlikely event that they do, we will refactor the code then.  Refactor is normal.  You have to refactor at least a little every time a requirement changes.  And when we refactor, then let's talk about whether we should use Singleton pattern again.  For now, if it ain't broke, don't fix it.

Ok, me again.  Some of these "rebuttals" I admit are pushing the limits of absurdity.  But well, all I can do is point to the original code as evidence of the thinking commonplace here.  Of course, at the end of the day, if people really insist that using the Singleton pattern as an alternative to registering proxies is the way to go, then I have to ask why we are bothering with the pretense of PureMVC in the first place.  But then that puts me in the position of advocating we either stop using the framework in favor of not having one at all, or using PureMVC standards because that's just the way you do it in PureMVC.  I've won with the latter argument in the past by virtue of just being frothy about it ("Well, if you feel that strongly about it ok...").  But I would rather be able to persuade folks of the merits of coding correctly.

Perhaps the problem here is not about the merits of PureMVC standards, but about having standards and following them consistently in the first place, even when the standard results in some "unnecessary" boilerplate at times (eg registering a Proxy that is never used by any other actor, never requires clean-up, etc.).  I'm going to stop here before I begin venting and focus on why I posted the original message, which is that I am looking for persuasive arguments to make for following the PureMVC standards even when doing so seems unnecessary for the above reasons.

Thanks for bearing with me.  I know this isn't the first time...
21  Announcements and General Discussion / Getting Started / Why should I bother to register my Proxy classes? on: May 24, 2011, 07:56:32
Ok, so I have come across something in our code base and it has caught me flat-footed.
Its audacity is so stunning that I don't know what to say to the person who implemented it.
So please explain to me what is wrong with the following:

The Mediator class has a global variable pointing to a proxy class.

var _proxy:MyProxy = new MyProxy();

Later, the Mediator class simply calls _proxy.retrieveData() (for example, in the onRegister() method).

Inside of MyProxy, a URLLoader instance retrieves the data from the server and then sends a notification. 

The Mediator picks up the notification, passes the data from _proxy to the viewComponent, and moves on.

Everything works fine but you will notice that nowhere is the proxy registered with the facade.  Because I mean really, why bother?

How do I correct this code and how do I explain the correction?  Or should I follow his example and just stop registering my Proxies when a global reference will do?  It does use less CPU cycles this way! :P
22  Announcements and General Discussion / Architecture / Re: Frustrating problem about what to do with data modified in a viewComponent on: March 23, 2011, 06:39:38
Cliff, thanks.

I think where I got lost was that actually this param-setting Mediator can have multiple instances.  But each instance, though the param-setting view classes may be the same, will end up having to send a different server request in response to a control panel notification (each view sets params for different data services).  Unfortunately, for simplicity's sake, I think I want each request to be handled by a unique Command/Proxy... which means it looks like I will have to ditch the one-size-fits-all param-setting Mediator class.

I don't know, this is a philosophical question perhaps, but I guess I prefer having lots of similar one-instance classes as opposed to having one catch-all class whose instantiation process is overly intricate and complicated... and susceptible to abuse down the road. 
As long as it is simple, sensible, and obvious, I would use one Mediator class with multiple instances, differentiated by mediatorName, but the above problem with what to do about unique server requests that have very different business logic (and therefore, in my opinion, require different notification names) may be the straw that breaks this camel's back.

If you think I may be giving up too easily, let me know.

Alternatively, what is your reaction to the idea of a single catch-all server request command that switches off its notification type and then handles a variety of business logic from there?  (my gut reaction is revulsion... but I'd like your opinion)  If I allow myself to do that, I could see possibly going back into the forest and coming out the other side.
23  Announcements and General Discussion / Architecture / Frustrating problem about what to do with data modified in a viewComponent on: March 23, 2011, 12:54:48
I have a frustrating problem that I can't figure out the solution to without breaking PureMVC convention.

I have two mediators for two separate views in the application.
One mediator is for a viewComponent that manipulates some data that eventually becomes the parameters of a server request.  This data is made from scratch.  It originates in the viewComponent based on user interaction.

The other mediator is for a viewComponent that serves as a control panel for, among other things, triggering the above mentioned server request (via a "ServerRequestCommand" notification).

My problem is, I cannot think of a way to grab the necessary parameters through the parameter-setting viewComponent without just directly calling a get method on its mediator.

But isn't this anti-pattern?
:
ServerRequestCommand extends SimpleCommand {
  public function execute(notification:INotification):void {
    var params:Array = ParamSettingViewCompMed(
      facade.retriveMediator("ParamSettingViewCompMed")
    ).getParams();
    //business logic follows...
  }
}

Even if I pass the parameters in the body of the command's notification (which seems correct), that just means the problem is moved from the command class to the control panel mediator class that sends the notification.

:
ControlPanelMediator extends Mediator {
  ...
  public function serverRequestButtonClickHandler(event:MouseEvent):void {
    var params:Array = ParamSettingViewCompMed(
      facade.retriveMediator("ParamSettingViewCompMed")
    ).getParams();
    sendNotification("ServerRequestCommand", params);
  }
}

Is my whole architecture screwed up?  I'd really like to get this right before implementing similar stuff down the road.

My general rule of thumb so far has been that only Proxy classes may have methods that are directly called by other actors (ie Commands and Mediators)--everything else goes through Notifications.
24  Announcements and General Discussion / Architecture / Re: Tying mediator's registration to view component's life cycle on: August 08, 2010, 10:24:37
Cliff, @jpwrunyan thanks for your feedbacks !

@jpwrunyan, both options you mentioned does not rely on the view component's life cycle. That's exactly my point!

Right, sorry.  I guess in my own convoluted way I was trying to agree with you on that point.  Sorta got sidetracked into talking about Mediators half-way through my own post...
25  Announcements and General Discussion / Architecture / Re: Tying mediator's registration to view component's life cycle on: August 05, 2010, 09:01:29
How are you instantiating these child components?  Is it all in MXML???
Anyway, I rarely use creation events to register a view component with a Mediator.

Rather, I would have the parent component create the child, add it, and then dispatch an event which its mediator catches and then handles (for example by registering another mediator for it).

Or, I would have the parent's Mediator instantiate the child itself as well as the child's mediator and then add the child to the viewComponent as necessary.  I think this is what you are advocating.

Either way, I have complete control over the ordering of the Mediators' instantiation and can expect predictable results from the overarching application.

But ideally, I would have some formal application level procedure for changing views, adding popups, etc. which would encompass all possibilities and obviate the question of how to deal with "child" mediators.  It's just me perhaps, but I find the idea of a Mediator being the "child" of another Mediator distasteful.  I think they should all be equal in the eyes of the application architecture regardless of where their viewComponent lies in the view hierarchy.  I'll stop there since I risk getting into a semantic argument that has nothing to do with your current post!
26  Announcements and General Discussion / Getting Started / Re: First PureMVC Project on: July 29, 2010, 10:47:26
For Alerts, I do it basically the way you describe. 

The Alert.show() logic might be inside my actual mainViewComponent and then if some other logic wants an Alert to be shown, it dispatches the notification, the MainViewMediator picks it up, and then tells the mainViewComponent to show an alert.  This allows the actual alert implementation to be independent from everything else.  If I decide to stop using Alert.show() and instead use PopUpManager, the logic is contained in the mainViewComponent--anyone can mess with it and not break the overall framework (or even know anything about it).  Convenient for handling little changes like styles or other Flex-dependent aspects of popups.

Maybe a distinction between advanced popup components and simple alerts in your application will make the right course of action clearer?
27  Announcements and General Discussion / Architecture / Re: Popup System: Commands or Mediators to handle popup interaction? on: July 25, 2010, 08:46:38
@sidedoor

I have the exact same situation here too.  The people who started working with the PureMVC framework didn't exactly understand it (nor did I originally), and they extended a lot of framework classes making them too-clever-by-half.  Then, like your project, the requirements outstripped the framework, and there's spaghetti all over the place.  You have my sympathy!

@cliff

thanks for the link.  I remember scouring the forums a long time back looking for how to handle popups best, but I guess I never found a reference to this page.  always appreciate your help!

edit: one point where I would differ with his approach is that he chooses to set his data using one single command and then accommodate different mediator classes in a switch statement (the setPopData() method).  In my case, this would lead to a monolithic switch statement.  Ergo, I will still probably keep the business logic for each popup in its own specific command/notification, and delegate the placement of popups on screen to the separate common shared notification.  Still, with a little tweaking, I think he could make his popup mediators have an interface for his setPopData() method and just pass some arbitrary data to it and leave the Mediator to take care of the rest.  Also, no problem putting some business logic in the Mediator's onRegister() in this case is there???  (I'm thinking specifically getting data from proxies and sending other notifications that might affect the rest of the application--this is what my class-specific commands currently do).

edit2: just so you can see concretely what I am doing, here are the two (very simple) commands for handling popups that I use currently:
:
public class AddPopUpCommand extends SimpleCommand {
public function AddPopUpCommand() {
super();
}

override public function execute(notification:INotification):void {
var popUp:UIComponent = UIComponent(notification.getBody());
var mainViewMediator:IMediator = facade.retrieveMediator(MainViewMediator.NAME);
var mainView:UIComponent = UIComponent(mainViewMediator.getViewComponent());

if (popUp.parent == mainView.systemManager) {
PopUpManager.bringToFront(popUp);
} else {
PopUpManager.addPopUp(popUp, mainView);
}
PopUpManager.centerPopUp(popUp);
}
}
:
public class RemovePopUpCommand extends SimpleCommand {
public function RemovePopUpCommand() {
super();
}

override public function execute(notification:INotification):void {
var popUp:UIComponent = UIComponent(notification.getBody());
var mainViewMediator:IMediator = facade.retrieveMediator(MainViewMediator.NAME);
var mainView:UIComponent = UIComponent(mainViewMediator.getViewComponent());

if (popUp.parent == mainView.systemManager) {
PopUpManager.removePopUp(popUp);
}
}
}

example of specific popup

:
public class ShowMyPopUpCommand extends SimpleCommand {
public function ShowMyPopUpCommand() {
super();
}

override public function execute(notification:INotification):void {
//frequently changing business logic goes here...
//most people can get by without defering Proxy and Mediator instantiation like this...

if (!facade.hasProxy(MyPopUpDataProxy.NAME)) {
facade.registerProxy(new MyPopUpDataProxy());
}

if (!facade.hasMediator(MyPopUpMediator.NAME)) {
facade.registerMediator(new MyPopUpMediator());
}

var myPopUpMediator:IMediator = facade.retrieveMediator(MyPopUpMediator.NAME);

sendNotification(ApplicationConstants.SHOW_POP_UP, myPopUpMediator.getViewComponent()); //this can also be in the Mediator's onRegister() method
}
}

Note that this is for standard PureMVC, not MultiCore.  You can get even more power out of these if you change the notification body from a reference to the popup into a VO that contains the popup and any other information geared towards common functionality (like if you want to check/instantiate your Mediators here as well, or specify different parents for the popup, etc.).  Also, in a perfect world, ShowMyPopUpCommand, ShowMyOtherPopUpCommand, and ShowMyYetAnotherPopUpCommand would all use the same logic structure and therefore become unnecessary--the necessary logic would all be in MyIdealAddPopUpCommand.  For me this just isn't doable right now (without that aforementioned monolithic switch statement).

For now I keep it simple so I can avoid painting myself into a corner.  This comes at the cost of having a lot of Command and Mediator classes in our project.  But if I knew for sure the final requirements for our project (ie no chance of specification changes/bloat), I would smarten this up.

Anyway, if you end up using/improving this, please let me know.  But I think your dream of not having a mediator for every type of popup is likely to become a nightmare if you pursue it.  I don't see that working out for you unless your project's management can guarantee there will be no functionality bloat.
28  Announcements and General Discussion / Architecture / Re: Popup System: Commands or Mediators to handle popup interaction? on: July 21, 2010, 11:57:06
Wow.  This seems a lot more complicated than necessary.  It may just be that I still don't grasp everything that's going on in the application that requires the complexity.

I will just suggest that it might be helpful to not think of popups as anything more special than your other view components.  Whether the view is attached to a ViewStack, is a static part of the application, etc. you will need some formal way of inserting a given view component into the (Flex/Flash) application's view hierarchy.

Most applications will dynamically change their view according to an event/notification.  Like navigating to a different screen via a main menu.  To do this, I send a notification with the view component as the body.  The notification is handled by the Mediator associated with the main view component.  That Mediator then calls logic on its own viewComponent, such as addChild() or calls PopupManager.addPopUp, whatever.  This process is completely independent from any other initialization/instantiation logic (registering proxies, mediators, etc).  It is simply a branch in the framework for displaying components that are essentially children of the main view.

I struggled with how to handle popups for a long time until I eventually came around to thinking of them as no different from any other dynamically displayed view component in the application.

Here's a concrete example of what I might do:
:
public class DisplayEmployeePopUpCommand extends SimpleCommand {
  override public function execute(notification:INotification):void {
    //get the mediator of the component I want to display, or instantiate it
    if (!facade.hasMediator(DisplayEmployeePopUpMediator.NAME)) {
      //I create the actual viewComponent inside DisplayEmployeePopUpMediator
      facade.registerMediator(new DisplayEmployeePopUpMediator());
    }
    var viewComponent:Object = facade.retriveMediator(DisplayEmployeePopUpMediator.NAME).viewComponent;
    sendNotification(ApplicationConstants.SHOW_POPUP, viewComponent);
    //any other necessary business logic can be handled by this command.
  }
}

ApplicationConstants.SHOW_POPUP is handled by the main view's mediator class.  It could also be handled by another command.  You could change the format of body if you like (I just give it the viewcomponent and that's good enough for my purposes).  You could add type to the notification if your popups have different display classifications (or if you wanted to expand and use this technique not just for popups, but for screen navigation, etc).  From here I think you can infer how I go about hiding popups, destroying them, etc.

As you can see, since the "popUp" is just a viewComponent with its own Mediator, I don't hammer my head against the desk trying to come up with some architecture for it and all other popups that encapsulates every scenario that might arise in my application.

It's just a view component with a Mediator which can handle anything that might arise on a client meeting by client meeting basis.  Inelegant, perhaps.  But simple and straightforward in my opinion.

Anyway, I hope this is at least food for thought.
29  Announcements and General Discussion / Getting Started / Re: Role of StageMediator? on: June 15, 2010, 06:19:58
Thanks again for the reply, Cliff.
I can't yet picture in my mind concretely what a 'service core' is and how I would snap in and out of it, but I will try to figure it out on my own first.  Very likely I will come back and ask for help.   ;)
30  Announcements and General Discussion / General Discussion / Re: Smart VO on: June 15, 2010, 06:14:06
I'm not sure yet exactly what you mean.  Does one single VO instance hold multiple XML objects that come individually from separate proxies?  If this is the case, then why not just have one Proxy also gather those various language XML files?  Then you would still have the 1 to 1 relationship between proxy and VO.

Or, just make yet another class (not necessarily a VO) that manages the functionality of "selected language" with the various language VOs.  I mean, you could have a collection object that holds these various language VO's which your application populates upon some Proxy notification.

Anyway, I might be misunderstanding you.
Pages: 1 [2] 3 4 ... 6