tag:robotlegs.tenderapp.com,2009-10-18:/discussions/questions/513-mediator-proliferationRobotlegs: Discussion 2012-01-11T11:30:02Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-04-21T09:24:18Z2011-04-21T09:24:18ZMediator Proliferation<div><p>It sounds wrong, but I can't really think of major advantages
except one big one: if you come back to this project, or someone
else needs to do changes you'll be searching in the mediators to
find out where you need to do your changes.<br>
It sounds to me though that this warns of an architectural flaw,
maybe your components have too much responsibility and "do" too
much? If the task at hand is different from the one the existing
mediator handles chances are that task shouldn't originate from the
same view component but from another (sub)component and therefore
be separately mediated.</p></div>creynderstag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-04-22T01:49:48Z2011-04-22T01:49:50ZMediator Proliferation<div><p>It turns out that you can only have one Mediator per Context,
per Class type, which seems like an unnecessary restriction. The
only reason it worked was because I had nested contexts.</p>
<p>I don't think my Views have too many responsibilities...I just
like tiny Classes. If it comes down to it, the Views I want to
multiply Mediate don't have any responsibilities in and of
themselves. They are visual representations of data the user is
editing--exactly the same views that will be used to present the
edited material to the end user. The Contexts and the attached
Mediators and Commands add the editing functionality around the
outside.</p>
<p>So, what I <em>want</em> to have is a Mediator that determines
whether the represented data is in the selected data collection or
not (based on mouse clicks on the View), another Mediator that
updates the CSSStyleDeclaration for the renderer showing the data,
and a third Mediator that opens Views representing textual data
(based on an event generated when the user clicks a second time on
the View representing the same data) for editing and propogates
changes to the text back to the Model when the View is closed for
editing. But unfortunately the MediatorMap actively prevents this
unless I want to add extra layers of Contexts...and then I have to
figure out how to manage all the communication and data among the
contexts.</p></div>Amy Blankenshiptag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-04-22T05:51:02Z2011-04-22T05:58:10ZMediator Proliferation<div><p>One solution would be to use the ViewInterfaceMediatorMap. You
can have a view implement multiple interfaces and map each of them
to a separate mediator.<br>
That will solve the one big problem I described above as well.</p>
<p>But still, it sounds to me you're grouping too much in one
view.</p></div>creynderstag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-04-22T16:52:10Z2011-04-22T16:52:10ZMediator Proliferation<div><p>Can I just check - some of this sounds to me like you've started
using the Mediator for a view Controller?</p>
<p>While the Mediator commonly sits in the view package (because
it's nice and easy to see which views have mediators that way),
it's a bridge between the view and application, not part of the
view tier itself.</p>
<p>I could be wrong - but if that's how you're using it then that's
the crux of your problem.</p>
<p>Alternatively, just compose your mediators in the normal way
that you'd use to share functionality in multiple configurations
across classes. Again, it sounds to me like you're trying to push
work on to the mediatorMap which doesn't really belong there (by
asking it to handle the composition).</p>
<p>There are lots of reasons why the one-to-one mediator-view
relationship was chosen, but if you want to make a
multi-mediator-per-view version then do go ahead and fork it and
fix it!</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-04-22T19:27:23Z2011-04-22T19:27:26ZMediator Proliferation<div><p>Right, Stray...none of the functionality really has anything to
do with the View in its purest form. You do a lot of eLearning, so
you should understand this. Imagine that you have a screen of data
that can have 1-n bits of formatted text, 1-n graphics, etc. So the
pure View is a DataGroup that has an itemRenderer representing each
piece of data, and each renderer is one of the Views I want to
separate out Mediation on.</p>
<p>In editing mode, I need to add more functionality than the
"dumb" displaying of the data, to make it easy for users to see
what is being edited and to make the Views behave properly while
being edited. In most cases, the Mediators are merely firing events
to move the Views into or out of selected state, but in some cases,
either because of the limitations of binding or because the pure
View should not have any facility for highlighting (this is not
needed by the View in the end, edited state), the Mediator needs to
do some work to make sure that the View state visually reflects the
state of the data.</p>
<p>I am not willing to add logic or components to the Views to
facilitate editing, but I don't see this as a problem. What I
<em>do</em> see as a problem is the artificial restriction on
multiple mediators imposed by Robotlegs. If I want to have
Mediators that listen for click events from the View in the
editing.selection package and other mediators that listen for "open
for editing" events from the event bus in the editing.editing
package, isn't that really my <em>own</em> business? It sticks in
my craw that my editing mediator needs to extend the selection one,
simply because of some stupid restriction in the Framework I'm
using.</p>
<p>creynders, I'm not sure how I could put <em>less</em> in my
Views, which are simply dumb displays of data objects, so I don't
follow your point.</p></div>Amy Blankenshiptag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-04-22T20:47:26Z2011-04-22T20:47:26ZMediator Proliferation<div><p>Hi Amy,</p>
<p>I think you mean "some work needs to be done", and not "the
mediator needs to do some work"... and you've complete ignored my
suggestion that you could compose your mediators to achieve the
same pick-and-mix results, and creynders suggestion to use the
Interface based mediatorMap utility, but anyway...</p>
<p>The Robotlegs framework is built to be the 20% of functionality
that solves 80% of people's problems, as efficiently as possible.
Not just for run-time efficiency, but also to minimise the
cognitive load created by the framework API.</p>
<p>You are in the very small minority who have found a case where
you would like a many-to-many 'mediator' situation. It's not that
we've 'stupidly restricted' it - you don't have a god given right
to multiple mediators that we've taken away from you out of idiocy.
We've provided (free) a framework which <em>enables</em> a single
mediator for each view, because this satisfies almost all use
cases.</p>
<p>If you would like to further contribute to the framework as
well, by creating an implementation of the mediatorMap which adds
the feature of multiple mediators-per-view, feel free. Open-source
is all about sharing the load. As we always say: fork it and fix
it.</p>
<p>If you don't feel yourself to be capable of that, then perhaps
have a little more respect for the people who <em>do</em> get the
work done to publish the tools that allow you to earn your living
more efficiently. We all have our weaknesses and limitations, and
no doubt there are some things that will change in RL 2 because of
the learning that comes from using-it-in-the-field, but the team
(Shaun, Joel, Robert & Till) behind Robotlegs are among the
least stupid people I have ever come across.</p>
<p>If you do feel yourself to be capable of building an alternative
multiple-mediator implementation then get on with building it.</p>
<p>Yes, it's certainly your business how you choose to use the
framework, but calling the implementation 'stupid' just because it
doesn't work how <em>you</em> currently want it to work is an
interesting way to go about engaging with the open-source
community.</p>
<p>You've been offered sensible work-arounds by people who are also
giving their time and energy free to try to understand your problem
and offer solutions. You have a very strange response to those
genuine gestures of assistance.</p>
<p>We don't really <em>do</em> flaming and disrespectful criticism
here.</p>
<p>I'm guessing that you don't intend to be offensive, and you're
just very frustrated with your code at the moment. If you want more
details about how to implement one of the alternative solutions I'm
sure people will be happy to help with a more detailed suggestion
if you can provide some sample code as a starting point.</p>
<p>Thanks,</p>
<p>Stray</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-04-22T21:53:55Z2011-04-22T21:53:57ZMediator Proliferation<div><p>Hi, Stray;</p>
<p>I'm a bit confused. What I was saying is that I actually do want
to compose Mediators, to use one per "thing" that I want to do. I'm
also not asking for a many-to-many mediator situation, but instead
a many to one situation (many Mediators all mediating the same
View, each with its own thing it cares about).</p>
<p>The reason I call the restriction stupid is that I can't think
of any technical reason why you couldn't allow this to happen--it
was my belief at the time that I said it that you probably could
simply stop throwing the error and allow people to do this if they
wanted to. Looking at the code, it seems that the reasoning behind
this problem is that the MediatorMap has a dictionary that looks up
one mapping per View Class.</p>
<p>And you're right, following the pattern used in the CommandMap
Class to allow multiple Commands to be mapped for the same Event
would be slightly less performant, as it would require nested
Dictionaries (or you could use a Chain of Responsibility pattern,
which might make the performance come out about even). However, if
it is good enough for the CommandMap, which arguably will be
mapping and unmapping more often than MediatorMap, why wouldn't it
be good enough for MediatorMap?</p>
<p>The fact that the different parts of the Framework don't behave
in the same way is certainly unexpected, and I might argue that
this inconsistency creates more cognitive load.</p>
<p>You're also correct in that I have only a limited amount of time
to work on side projects and this time is almost entirely spoken
for, so it is unlikely that I would be able to patch MediatorMap
and contribute it back to the community (though I might well just
patch it for myself, since that would not require all the git
setup, etc.).</p>
<p>I have never understood why people equate "I don't like what
your code does in this instance" with "Your code is stupid and so
are you, " and honestly I hadn't expected it to be taken that way
by this group of people, particularly you. I deeply apologize that
what I said in a moment of thoughtlessness affected you in this
way.</p>
<p>I am not sure if the workarounds are actually sensible, as with
the exception of ViewInterfaceMediatorMap I haven't been able to
see a connection to my actual issue. That may be that I am not
understanding what I am being told, but equally, it may be that I
haven't communicated effectively what I am trying to address.</p>
<p>The reason I didn't reply to the suggestions about the
ViewInterfaceMediatorMap is that I considered its possible
appropriateness obvious, but I haven't yet had time to consider
whether it will require implementation of multiple interfaces which
will violate my goal of <em>no</em> logic that has anything to do
with editing in the final displayed views. I can be as inflexible
as you in preserving purity of intention in my code :-).</p>
<p>I'm not frustrated with my code, per se, because it works.
Instead, I am frustrated by being forced to put things in places
that make no sense according to how my code <em>should</em> be
organized and to violate SRP, in effect by the very Framework I
selected to allow me to do the opposite. This is very similar to
the frustration I feel in working with TLF and realizing that a lot
of its transformations go on entirely in the View and there's no
way to picture them in data.</p>
<p>While there's no deity-of-your-choice-given right to anything in
this world, it's disappointing to find that you've gotten so far
down the road and the mechanics of the tool are dictating decisions
for you. I was talking to a friend at 360Flex who is having a
similar experience with Mate.</p>
<p>Anyway, you're right that I was not intending to be offensive,
and I apologize again for having been offensive.</p></div>Amy Blankenshiptag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-04-23T11:24:16Z2011-04-23T11:24:16ZMediator Proliferation<div><p>Hi Amy,</p>
<p>I didn't mean that you should put less in your views, I meant
that what you see as one view is in my opinion more than one. But
obviously I don't know the exact case, so it could be it really IS
impossible to further break it down. Anyway, I think you do know
now how to solve the problem, right?</p></div>creynderstag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-04-24T17:18:05Z2011-04-24T17:18:07ZMediator Proliferation<div><p>Hi, creynders;</p>
<p>If I read you correctly, it seems you are saying that I should
actually have one or more separate views to use during editing,
rather than using the runtime view and using Mediators and Commands
to add functionality to them. I have a number of reasons for not
wanting to do that, but the primary one is that I want to make sure
I'm truly offering WYSTWIG editing--if they are, in fact, editing
the actual View that will be used, you can't get much more fidelity
than that.</p>
<p>I actually have never had an actual <em>problem</em>, per se, as
it is always possible to get the logic to do what you want. This is
more of a philosophical discussion as to whether my Mediation
approach makes sense. And there's the issue that we have a third
layer that we may choose to implement in the future--a practice
layer, where we provide guided practice on top of the editing
layer. And when we get to that layer, it will be really important
to maintain clarity and good architecture.</p>
<p>At that point, it may make sense to just extend the editing
Mediators to add on functionality to guide the practice, but it may
equally make more sense to have independent Mediators. When I get
to that point, I'll come back and let you know how it went :-).</p></div>Amy Blankenshiptag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-04-30T23:05:31Z2011-04-30T23:05:31ZMediator Proliferation<div><p>Hello Amy,</p>
<p>I am normally solve these kind of design mode issues by
'decorating' the plain view with a editing version which would
offer the editing functionality. For example, if you have a text
element which should be editable after a double click.</p>
<p>I would have a TextElement which renders text and then a
EditableTextElement which takes an instance of TextElement which
adds the editing related views. In my case a little toolbar for
bold, italic and a tab stop ruler. E.g. new EditableTextElement(
myTextElement ).</p>
<p>Next TextElement would have a method like setTextStyle and
getTextStyle to change the formatting of the text. Of course, you
could go with mediators but in the above example its a Flex
component which encapsulates this all.</p></div>Weyerttag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-05-01T00:07:24Z2011-05-02T13:29:32ZMediator Proliferation<div><p>Hi, Weyert;</p>
<p>That's interesting, but it's a completely different approach to
mine. I personally don't believe in editing Views. Instead, I edit
data as far as is practical, When the Flex Framework forces me to
edit in the View, like changing the actual Test, I keep as tight
control over that process as I can.</p>
<p>In this case, each Text (data) object has a separate member
which describes its formatting. When the Mediator determines that
the text has been selected, a reference to that formatting object
is passed to the PresentationModel of the toolbar for editing. When
the user changes the formatting, this launches a Command that edits
the Model.</p>
<p>The problem is that something needs to call the
toCSSStyleDeclaration on the styling object and set that style on
the renderer that happens to be representing that data at the
moment. But I absolutely will not compormise and make my View in
any way aware of the fact that it is being editied, either for that
or in order to highlight it.</p>
<p>Most of the issues I've seen with tight coupling and poor
maintainability have to do with treating the View as integral to
the editing process, rather than a means to collect user gestures
that then can be translated into data changes on the Model by some
other agency.</p>
<p>I'm actually using my Mediators for decoration, in order to add
the communication needed and perform minor updates to indicated or
assist with editing. Not everyone agrees that Mediators can/should
be viewed as Decorators, but I believe that's as valid an opinion
as any other.</p>
<p>When I get to the next phase, I will need to decide whether it
makes sense to extend/fix MediatorMap to allow multiple Mediators
to be attached to the same View Class, or whether I should just use
two or more MdiatorMaps within the same Context. Because of course
there shouldn't be any limit to the number of Decorators you can
apply to the same instance---you should apply as many as you need
and make sense.</p></div>Amy Blankenshiptag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-05-02T14:03:01Z2011-05-02T14:03:01ZMediator Proliferation<div><p>Hi Amy,</p>
<p>you still haven't responded to the suggestion to simply
implement the decorator pattern from within (or around) each
mediator, rather than through the mediatorMap itself.</p>
<p>Nobody disagrees that decorator-mediators is a nice concept,
it's just not in the 80% solutions that we target with robotlegs
(which is why I objected to your calling it a stupid restriction -
to me that suggested that the people who thought it was a
reasonable restriction were actually stupid).</p>
<p>Mapping a single event to multiple commands is well within that
80% (even to implement bootstrapping requires multiple Commands
mapped to the ContextEvents).</p>
<p>Multiple-mediators-per-view is - in our judgement - outside of
the 80%. If it wasn't then you'd see a clamour of posts on here
about it, where actually it has come up only 2 or 3 times in
thousands of posts.</p>
<p>Definitely don't use 2 or more mediator maps within the same
context. That would result in doubling (or more) the amount of
heavy describe-type work being done in response to every single
display object that hits / leaves the stage. Ouch.</p>
<p>I know you think that it's <em>just</em> a case of expanding the
dictionary to have an additional dimension, but for various reasons
to do with the clean-up process it's significantly more complex
than that and would lead to having to do multiple checks when the
view leaves the stage and/or a mediator is unmapped. The CommandMap
deals with moment-to-moment situations, the MediatorMap has to deal
with ongoing state issues, not to mention the flex-lifecycle
(you'll notice there are about 6 workarounds for this in the
mediator/mediatorMap code).</p>
<p>The mediatorMap is already the performance bottleneck in most
Robotlegs applications. This is why we didn't integrate the
excellent viewInterface version when it was offered - even a small
performance hit is problematic, so we determined that it was better
to offer it as a utility.</p>
<p>That said, if you do find a method for doing multiple-mediators
without a loss of performance then we'd be <em>really</em>
interested to see it.</p>
<p>I really can't see a problem with implementing the decorator
aspect from inside the different mediators, except potentially
losing state if you want to be able to change the
decorator-configuration at runtime and your mediators are stateful
(which they shouldn't be, ideally). You'd actually be switching out
sets of mediators rather than decorating while leaving the existing
mediators in place.</p>
<p>My best thought so far for a way around this is a
MediatorDecorator utility which has the mediatorMap injected (so it
can look up mediators for views) and wraps the decorators around
the mediators as required. Mediators would then have to do some
sort of clean up action on their own decorators when they are
removed.</p>
<pre>
<code>mediatorDecorator.addDecorator(SomeView, SomeViewDecorator);
mediatorDecorator.removeDecorator(SomeView, SomeViewDecorator);</code>
</pre>
<p>Your base mediator would need to be a DecoratorMediator that had
hooks for these decorators. You have more detail about what you
need to do, so I don't know whether this would actually achieve
what you're looking for.</p>
<p>The first stumbling block I can see is that there's no way of
guaranteeing that the mediatorMap is giving you back an instance of
DecoratorMediator, rather than just a vanilla Mediator, so you'd
need to think about how to ensure that your hooks are present. Most
likely you could actually map the decorateable-mediators through
your own utility rather than into the mediatorMap direct, and then
you could cache the bone-fide types as you go.</p>
<p>If it does fix your problem but it's not something you have the
time to tackle then I can put it on our todo list - which is a
little long at the moment I'm afraid, but we'd get there
eventually.</p>
<p>Stray</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-05-29T16:56:03Z2011-05-29T16:56:03ZMediator Proliferation<div><p>Hi, Stray;</p>
<p>I am really sorry...your reply went into my junk mail folder
:-).</p>
<p>The reason I don't want to implement Decorator <em>within</em>
the Mediator because<br>
the Mediator would then need [Inject] variables for all of the
Decorators it<br>
is managing, even though the Mediator, itself, doesn't need
that<br>
information. One reason we use automated DI is because we've
decided that<br>
this is not good practice--Classes should only need to directly
know about<br>
information they're using, not information their children need.</p>
<p>Decorators <em>around</em> the Mediators could potentially work,
but seems sort of<br>
fudgy compared to decorating the Views themselves, which is what
the goal<br>
really is. I don't believe you'd really need a DecoratorMediator,
since the<br>
whole idea behind decoration is that the thing being decorated has
no idea<br>
that it is involved in such a relationship.</p>
<p>MPO is that allowing more than one Mediator per view might be
very close in<br>
performance (possibly better) to having a separate decorator map
that is<br>
then traversing the mediator map.</p>
<p>It seems to me that all MediatorMaps in the same Context would
share an<br>
Injector (or is it the Reflector that does that bit?), so wouldn't
that<br>
shared Injector/Reflector do all of the describeType work? My
understanding<br>
is that once this is done once for a Class, it is cached and reused
for<br>
future requests.</p>
<p>I think the biggest issue for trying to allow MediatorMap is
backward<br>
compatibility--unmap doesn't have a parameter to allow you to just
unmap one<br>
of multiple different mappings for the same thing. For backward<br>
compatibility, what do you do when someone has multiple mappings
and calls<br>
unmap() without a parameter that says which one?</p>
<p>I was actually surprised to read speed tests recently that show
Dictionary<br>
access is actually much faster than I thought<br>
(<a href=
"http://www.zombieflambe.com/actionscript-3/as3-dictionary-class-array-object-benchmark/">http://www.zombieflambe.com/actionscript-3/as3-dictionary-class-arr...</a>),
so I don't think having multiple MediatorMaps sharing the same<br>
IInjector/IReflector would necessarily have performance issues.
Since each<br>
map would handle its own adding and cleaning up, I don't even see
a<br>
performance hit with that.</p>
<p>Thoughts?</p>
<p>-Amy</p>
<hr>
<p>From: "Stray"<br>
<a>tender+dbb28257892afad3e5fef96af5b84c6b41ac6ce03@tenderapp.com</a><br>
Sent: Monday, May 02, 2011 10:03 AM<br>
To: <a href=
"mailto:amy@magnoliamultimedia.com">amy@magnoliamultimedia.com</a><br>
Subject: Re: Mediator Proliferation [Questions]</p></div>Amy Blankenship (Magnolia Multimedia)tag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-05-29T17:52:30Z2011-05-29T17:52:30ZMediator Proliferation<div><p>Hi Amy,</p>
<p>it's not the injector that is the bottleneck, it's the listening
and interrogating every single thing that winds up on the display
list. If you have 2 things listening you double that work.</p>
<p>Every item - most of which are not useful - would be checked
more than once. The mediator cache (which directs view classes to
mediator classes) is not part of the injector (the injector /
reflector are in a layer which is separate to architecture), and
the contents of one cache and any other wouldn't necessarily be the
same, so it's hard to see how this part could be sped up. In
addition, there is a problem with caching in general in the
mediatorMap, because mappings are dynamic, and so it's not
straightforward to manage the state of the cache, as rules may get
out of sync with mappings over the course of the app's
lifetime.</p>
<p>So - having more than one map is going to be difficult to
optimise. Which isn't to say it can't be done - but the
implementation would be quite different from the existing
mediatorMap, so simply implementing multiple instances of that
mediatorMap is not a viable solution, and does cause substantial
slow down in a project where views are frequently coming and
going.</p>
<p>As you can see... simply deciding what 'decorator mediator map'
means in terms of API is not trivial. There's quite a big
difference between what a many-to-one mediator map and a one-to-one
mediator map need. The issues around unmap are - as you say -
unclear.</p>
<p>I don't think the mediators would need to inject variables for
all the decorators - surely they would only need a single factory
to be injected? You'd use a command to configure this factory with
mappings against the mediator and view types (just as you do with
the mediatorMap against view types), and the whole thing would flow
from there - something like...</p>
<p>public class SomeMediator {</p>
<pre>
<code>[Inject]
public var decoratorMediatorFactory:IMediatorFactory;
[Inject]
public var view:SomeView;
protected var decoratorMediator:IDecoratorMediator;
public override function onRegister():void
{
// may as well pass classes as we know them, avoiding the need to describe type
decoratorMediator = decoratorMediatorFactory.createMediator(SomeMediator, SomeView);
decoratorMediator.onRegister();
}
public override function onRemove():void
{
decoratorMediator.onRemove();
}</code>
</pre>
<p>}</p>
<p>At run time you would then use the decoratorMediatorFactory to
manage the adding / removing of decorators from any particular view
while the view is live, using the decorators like a linked list:
splice the chain simply by adjusting the parent/child
relationships. I imagine that would be quite efficient.</p>
<p>Even better - the injection of the factory and the basic
creation / removal logic could be shifted to a base class that you
extend instead of the vanilla Mediator - though I think you'd lose
the benefit of passing the classes rather than the instances of
view and mediator.</p>
<p>This implementation isn't perfect of course, it's just what I've
whistled up in a few minutes - but my point remains that it's
<em>relatively</em> simple to implement a decorated-mediator
approach using the existing mediator map implementation with some
very minor additions.</p>
<p>Out of interest - what's your reasoning behind the comment that
things-being-decorated-don't-know-that-they're-decorators? My
understanding is that the decorator pattern implies composition,
where the decorators have a reference to the component below them
in the chain. They're ignorant of their parent, but they're aware
of their child (ie they're like a linked-list with next but not
previous) - otherwise how could one implement it? That makes me
think maybe you didn't mean decorators after all?</p>
<p>Perhaps you meant covariance? There's an interesting spin on
covariant mediators here: <a href=
"https://github.com/dnalot/robotlegs-utilities-variance">https://github.com/dnalot/robotlegs-utilities-variance</a></p>
<p>I'm not sure whether it's production-ready yet, or whether it
fits your needs.</p>
<p>We're about to start the process of scoping Robotlegs 2 in
earnest (at the end of June), and we'll certainly be considering
mediators and the mediatorMap as part of that. If you do have time
before then to at least scope the behaviours you're looking for
then we'll throw it in the pot.</p>
<p>In an effort to keep it light, it's unlikely that RL 2 will
(out-of-the-box) implement all the extra features people have
requested (that would be impossible). But we will be paying
attention to making sure that we provide hooks that support these
kinds of extensions. It'll still fall to the first person who wants
the functionality enough to actually build it to provide the
initial implementation, but if people can clearly describe what
they need then we can at least make efforts to support that
process.</p>
<p>Stray</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-05-29T18:46:17Z2011-05-29T18:46:17ZMediator Proliferation<div><p>Hi, Stray;</p>
<p>Perhaps you could do some sort of guarded event mapping shared
between<br>
multiple mediatorMaps to allow them to handle the listening and
reacting to<br>
newly instantiated Views (where one guard can call multiple
result<br>
functions). Perhaps Signals could be used for this, but of course
that then<br>
creates a dependency to another Library.</p>
<p>I see what you mean about injecting the factory, because at that
point you<br>
can also let the Injector inject dependencies that the Factory
needs to<br>
create the Decorators. I was assuming more that you were using it
where the<br>
Mediator is also creating new Decorators, which also violates a
couple of<br>
different rules ;-). It seems that if you take the approach that
you<br>
advocate below, you might as well just use child injection rules
and<br>
determining which child you get based on some other value you
receive by<br>
injection--the Injector is itself a Factory, so might as well make
use of it<br>
in this situation.</p>
<p>That might, in fact, be an effective way to deal with this
situation. I<br>
will think on it further and see if I can put together an example
that uses<br>
this, as even if I can't get it into git I can post it to a blog
and it<br>
should still be useful.</p>
<p>To answer your question: Yes, the decorator knows about what it
is<br>
decorating. But the thing it is decorating has no idea it is
being<br>
decorated, and doesn't provide any additional functionality to
allow for it<br>
to be decorated (besides something like events, that can be used
by<br>
decorators or anything else).</p>
<p>I believe the covariant Mediators is pretty much the opposite of
what I am<br>
looking for--it allows you to Mediate multiple subclasses of the
same View<br>
base class with the same View. I'll admit this is something I've
wanted in<br>
the past--until all the sudden I was showing miniature versions of
the same<br>
View as a thumbnail and I needed to turn off Mediation, which was
easy to do<br>
with a stub subclass. :-)</p>
<p>OK, I had a blog post planned for today, so
must...stop...discussing. For<br>
today at least ;-)</p>
<p>TTL;</p>
<h2>Amy</h2>
<p>From: "Stray"<br>
<a>tender+dbb28257892afad3e5fef96af5b84c6b41ac6ce03@tenderapp.com</a><br>
Sent: Sunday, May 29, 2011 1:52 PM<br>
To: <a>amy@magnoliamultimedia.com</a><br>
Subject: Re: Mediator Proliferation [Questions]</p></div>Amy Blankenship (Magnolia Multimedia)tag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-06-03T10:43:57Z2011-06-03T10:43:57ZMediator Proliferation<div><p>Hi Amy,</p>
<p>the injector wouldn't have the onRegister / onRemove etc logic.
So I think that would be a solution of limited use. I'd also prefer
to see a strong-typed solution that declares intent whenever
possible... and an API that limits the scope appropriately. If you
just inject the normal Injector into the mediator then you have
access to a powerful API most of which is not relevant in that
context.</p>
<p>Anyway - I'm sure you'll figure something out when you're of a
mind to build it.</p>
<p>Stray</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-06-05T14:06:48Z2011-06-05T14:06:48ZMediator Proliferation<div><p>That's not what I was talking about. I agree that you shouldn't
inject the<br>
Injector itself except in really exceptional circumstances.</p>
<p>The ideal syntax would look something like this:</p>
<p>injectorForViewA = injector.createChild();<br>
injectorForViewB = injector.createChild();<br>
...</p>
<p>//default decorators injector.mapClass(AbstractPurpose1Decorator
);<br>
injector.mapClass(AbstractPurpose2Decorator);<br>
...</p>
<p>//specific decorators
injectorForViewA.mapClass(Purpose1DecoratorForViewA); //use default
purpose<br>
2 decorator</p>
<p>injectorForViewB.mapClass(Purpose1DecoratorForViewB);<br>
injectorForViewB.mapClass(Purpose2DecoratorForViewB);</p>
<p>mediatorMap.mapView(ViewA, ViewAMediator, null, true, true,<br>
injectorForViewA);<br>
mediatorMap.mapView(ViewB, ViewAMediator, null, true, true,<br>
injectorForViewB);</p>
<p>Both mediators would then look like:</p>
<p>[Inject] public var
purposeADecorator:AbstractPurposeADecorator;<br>
[Inject] public var
purposeBDecorator:AbstractoPurposeBDecorator;</p>
<p>override public function onRegister():void {</p>
<pre>
<code>purposeADecorator.decorate(viewComponent as UIComponent);
purposeBDecorator.decorate(viewComponent as UIComponent);</code>
</pre>
<p>}</p>
<p>This is more typesafe than using</p>
<p>[Inject (name='injectorForViewA")] public var
purposeADecorator;</p>
<p>[Inject (name='injectorForViewA")] public var
purposeBDecorator;</p>
<p>and Rules, though there may be a way to handle this using rules
already<br>
where the mapView signature would not need to change and we could
still<br>
avoid having the Mediator know about the Rule's name. That's what I
intend<br>
to investigate before my next blog post about the Robotlegs
Injector (the<br>
first part is here<br>
<a href=
"http://riarockstars.com/2011/05/31/understanding-the-robotlegs-injector-the-robots-are-running-the-factory/">
http://riarockstars.com/2011/05/31/understanding-the-robotlegs-inje...</a>).<br>
This whole discussion might be obviated by Till's upcoming
toFactory() work<br>
anyway, but it's worth thinking about, I think.</p>
<p>It seems to me that solving this problem in some way or other
could be<br>
useful, not just for this application, but for many others.</p>
<p>FWIW;</p>
<p>Amy</p>
<hr>
<p>From: "Stray"<br>
<a>tender+dbb28257892afad3e5fef96af5b84c6b41ac6ce03@tenderapp.com</a><br>
Sent: Friday, June 03, 2011 6:44 AM<br>
To: <a>amy@magnoliamultimedia.com</a><br>
Subject: Re: Mediator Proliferation [Questions]</p></div>Amy Blankenship (Magnolia Multimedia)tag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-06-05T19:33:37Z2011-06-05T19:33:37ZMediator Proliferation<div><p>Hi Amy,</p>
<p>now you've completely lost me. I thought it was the mediators
you were trying to decorate, not the views?</p>
<p>So, why is the decorator decorating the view? Surely you want to
be decorating the mediator? Otherwise you're implying that
purposeADecorator is in itself another view - at which point this
feels like the domain of the view map and not much to do with
mediators at all.</p>
<p>This seems like it has now strayed a long way from the purpose
of mediators (to provide event relaying for the view), so I'm not
even sure that I understood your original intent correctly. I had
thought that you wanted to be able to provide a single view with
multiple mediators - yes? That was your original complaint - that
it was a 'stupid' restriction ;) And that if only it was possible
to assign 2 mediators to one view, all would be solved?</p>
<p>So - I'm obviously not on the same page in terms of what you're
looking for.</p>
<p>If you do come up with a solution, feel free to share it with
the community,</p>
<p>Stray</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-06-05T20:55:10Z2011-06-05T20:55:10ZMediator Proliferation<div><p>No, my original intent was that Mediators ARE decorators of the
Views, and<br>
that you should be able to apply as many of them as you like, and
they<br>
should all be ignorant of each other. There are many ways in which
a View<br>
might be updated as a result of changes in the model, and it
simplifies the<br>
design of the Decorators (which also, in my original ideal, are
Mediators)<br>
if each purpose is served by a separate Mediator Class.</p>
<p>If the Mediators are decorating each other, they're not ignorant
of each<br>
other, are they?</p>
<p>The purpose of the Decorator might <em>affect</em> the View
(such as to highlight<br>
it when it is "selected" or update its CSSStyleDeclaration when an
Object<br>
property changes from "normal" to "bold"). And, in fact, some
Decorators<br>
might well <em>add</em> View elements without the knowledge of the
View (such as a<br>
button that would delete the object when it is clicked). And that
element,<br>
once added by the Decorator, would indeed be added to the Display
List and<br>
Mediated normally (until removed from the Display List by the
Decorator).<br>
But none of these things actually <em>is</em> a View. It's a set of
functionality<br>
to be layered on top of a View. And there's no reason that the
CSSStyle<br>
decorator (or Mediator, ideally) needs to know about the Decorator
that is<br>
responsible for making sure a selected item looks and acts
selected. And if<br>
these Decorators can't be Mediators (which you assure me they
can't), then<br>
the Mediator should know as little about them as possible, and they
have no<br>
need to know about a Mediator.</p>
<p>Weyert suggested (and I considered it not to be a terrible idea
in the<br>
absence of multiple Mediators per View) that Mediators could be
used simply<br>
to apply as many Decorators as needed to a View. My biggest issue
with that<br>
idea was that I would not want my Mediators to know anything about
how to<br>
instantiate the Decorators or what they do. This could be resolved
by<br>
moving the instantiation part of creating the Decorator out to an
Injector<br>
and using it as a factory. However, it makes far more sense for
the<br>
Decorator to <em>be</em> a Mediator, because the Mediator is
already set up to both<br>
know about the View it is Mediating and the Event Bus where the
Events it<br>
need to use to update the View are occurring. The issue is a
technical<br>
one--that the mediatorMap is simply not robust enough to allow this
to<br>
happen.</p>
<p>In your mind, the purpose of Mediators is to respond to
Framework events,<br>
but in my mind the Mediators are like miniature jockeys sitting on
the backs<br>
of incredibly stupid horses bred only to do one thing. I
deliberately keep<br>
my Views dumb, dumb, dumb, and my Mediators give them more
direction and<br>
functionality. This is especially important in the application
we're<br>
talking about, where the View has absolutely no idea it is being
edited, and<br>
all the editing functionality is being added to the View on the
sly, through<br>
Mediators. Also, it's so easy to inject the Event Bus into pretty
much<br>
anything, a Decorator, a PresentationModel, or whatever, that
<em>only</em> seeing<br>
Mediators as event relayers isn't that useful IMO, unless you can
use<br>
mediatorMap to layer on as many Mediators as you need (more
functionality<br>
through Composition)--which, according to you, isn't feasible.</p>
<p>My intention has always been "How do I layer many independent
Decorators on<br>
top of my View," NOT "How do I decorate Mediators," which would be
pretty<br>
weird relative to my original question--it would suggest that I
wanted the<br>
Mediators to wrap around EACH OTHER and thus at least some of them
would<br>
know about each other. That's not my understanding of how
Decorators work,<br>
nor is it a concept I find especially attractive.</p>
<p>Keep in mind what happens if you have two (or more) independent
Contexts,<br>
both more or less looking at the same part of the Display list and
a new<br>
View is added to the Display List. If both Contexts have a mediator
mapping<br>
for the same View, you will get two different Mediators, unaware of
one<br>
another, both mediating the same View. Now, edit the
eventDispatcher<br>
injection mapping so that both are sharing an event bus. The
behavior you<br>
get in this situation is exactly what I want, but it doesn't scale.
If you<br>
keep overlapping more and more Contexts every time you want a new
layer of<br>
Mediation, you will eventually get a performance issue.</p>
<p>But I think that you're looking at this problem a bit too
specifically--as<br>
"how do we solve the Decoration issue," whereas the longer I look
at it, the more it becomes "how do I enable Mediators for different
Views to get<br>
slightly different information without resorting to magic strings."
There<br>
are probably lots of places where we could make use of Composition
within<br>
the same Mediator rather than creating a new Mediator for a
slightly<br>
different View/piece of data if we could do this.</p>
<p>The problem with using the ViewMap for this is that the View is
actually<br>
being Decorated, not being given information that can be injected
into any<br>
of its member variables--the View is completely unaware that any of
this is<br>
going on (and rightly so).</p>
<p>-Amy</p>
<hr>
<p>From: "Stray"<br>
<a href=
"mailto:tender+dbb28257892afad3e5fef96af5b84c6b41ac6ce03@tenderapp.com">
tender+dbb28257892afad3e5fef96af5b84c6b41ac6ce03@tenderapp.com</a><br>
Sent: Sunday, June 05, 2011 3:33 PM<br>
To: <a href=
"mailto:amy@magnoliamultimedia.com">amy@magnoliamultimedia.com</a>;
<a href=
"mailto:amy@magnoliamultimedia.com">amy@magnoliamultimedia.com</a><br>
Subject: Re: Mediator Proliferation [Questions]</p></div>Amy Blankenship (Magnolia Multimedia)tag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-06-06T10:06:36Z2011-06-06T10:06:36ZMediator Proliferation<div><p>Hi Amy,</p>
<p>While you're free to define the solutions to your problems any
way you like, if the solution we provide isn't even a close match
with your need then perhaps it's time to make your own, rather than
attempt to bend the one we provided into submission?</p>
<p>You're redefining the mediator as a view controller - our
mediatorMap implementation has only very limited support for this
strategy. I don't have a disagreement with the dumb-view /
view-controller set up - I just don't think using mediators
(stateless yada yada) as view controllers is the only, or optimal,
solution.</p>
<p>It's likely that we'll support view-controller creation through
Robotlegs 2 in some way, but right now, as built, our mediator set
up is not suited to this.</p>
<p>I still disagree that the meaning of decorator doesn't imply
that the decorator can stand in for the thing being decorated...
but anyway...</p>
<p>I just fundamentally believe that there is a simpler solution to
your problem - one that doesn't involve using Robotlegs for
anything other than a hook to kick off your custom behaviour.</p>
<p>I certainly don't think multiple contexts are particularly
relevant. Yes, they would achieve the execution logic that you
want, but you could use a totally inappropriate solution so solve
almost any problem in programming - it doesn't really get you very
far. (I seem to remember that that's what flash 4 and 5 programming
was based on - using enterFrame loops to do all sorts of logic with
invisible movieclips on stage all over the place!)</p>
<p>Maybe it's time to stop talking and get building? I'd be
interested to see a proof of concept - the tests alone would clear
up my confusion about what it is that you're trying to achieve.</p>
<p>Stray</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-06-06T13:40:51Z2011-06-06T13:40:51ZMediator Proliferation<div><p>Hi Amy,</p>
<p>Have a look at: <a href=
"https://github.com/dnalot/robotlegs-utilities-variance/">https://github.com/dnalot/robotlegs-utilities-variance/</a></p>
<p>It provides covariant mediation (mapping mediators to
interfaces, super types etc), which in itself necessitates
multi-mediator mapping.</p>
<p>If you find it to suit your needs please post back here with
feedback.</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/67616462011-06-06T14:49:10Z2011-06-06T14:49:10ZMediator Proliferation<div><p>Ah, I see that this util has already been mentioned. Have you
tried it out? You can map without covariance (third param):</p>
<p>function mapMediator(viewType:Class, mediatorType:Class,
covariant:Boolean = true):void;</p></div>Shaun Smith