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:

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!

But you say that the Mediator creates a 'global' variable (i.e. one that any actor in the system can see). So, I assume that instead, it is actually declared like:

Code:

public static var _proxy:MyProxy = new MyProxy();

?

If so, then it is bad because for other actors to reach that Proxy instance, they have to reference the Mediator which has nothing whatsoever to do with the Proxy. Bad coupling.

However, if it is actually not a 'global' variable, but instead, just an instance variable, defined like:

Code:

private var _proxy:MyProxy = new MyProxy();

or

Code:

protected var _proxy:MyProxy = new MyProxy();

or

Code:

public var _proxy:MyProxy = new MyProxy();

so that any method in the Mediator instance can see it; it is fine for the Mediator to create a collaboration with the Proxy that way, except it should not initialize the Proxy class with a new instance, but should instead retrieve it from the Model via the Facade.

You register the Proxy...1) So that more than one actor can retrieve it. 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. 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.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.

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:

Code:

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).

Quote

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.

Quote

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?

Quote

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?

Quote

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.

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?

I never advocated making Proxies into Singletons. If a Proxy is used according to best practices (i.e. registered with the Model), then you can have it either way, by convention. You can register and retrieve it by its NAME constant, and you'll never have more than one registered. However if you need multiple instances, you can use the same idioms and just create unique names for each registered instance. But making it a Singleton when there is already a Singleton registry (the Model) is pointless.

Quote

Furthermore, when have we ever unregistered a Proxy?

I don't know, I don't work on your team. But I've worked on very large projects where it was necessary to only have registered the parts of the app that are needed at any given time.

Quote

Again, no other actor will ever need this Proxy. It's in the documentation. The requirements are not going to change.

Famous last words...

Quote

Some of these "rebuttals" I admit are pushing the limits of absurdity.

Yep. It sounds as if the last step before pushing this app off the loading dock will be to seal it in concrete so it can never again change, therefore, it's fine to just do things however. 'Git r dun', in the parlance of the day. You've saved a whole line of code this way, surely that's a big win for the team somehow.

Quote

Perhaps the problem here is not about the merits of PureMVC standards, but about having standards and following them consistently in the first place...

I believe that's the heart of the matter. I've described the various reasons for registering the Proxy, but all the rebuttals are based on "we're never going to reap any of those benefits with this one actor, so lets just do it differently." (see the attached photo for my precise feelings on that line of thinking).

But if other developers should join the team later to maintain the app or add functionality, then you'll do them a kindness by following conventions now. When I come onto a job and look at an application for the first time, and all the conventions have been followed, I have less questions like 'why was this done' and 'is it safe to touch this part?' I move more swiftly into understanding what the app is actually doing.