Home >
What is Mate?
Mate is the new kid on the block in the Flex framework world. It’s an MXML-based Flex framework that - like its colleagues - encourages the use of the MVC architectural pattern.
There’s been plenty of buzz around the campfire over Mate. After some investigation it quickly becomes apparent that its popularity is well warranted.
It is developed and run by AsFusion.
The Model-View-Controller Pattern
Just briefly, we’ll reiterate the MVC archetype.
- The Model is where our data is stored; it shouldn’t know about the View or the Controller.
- The View is the user interface of the application.
- The Controller is the worker; it listens for events and updates the Model.
In Flex, properties from the Model are databound to the View so that updating the Model is automatically reflected in the View.
Why Mate?
Mate is readable. Mate is light.
It’s a Flex framework built on the idea of an Event Map. That is, a collection of handlers to respond to incoming events and perform any number of appropriate actions. In Cairngorm, you could think of it as an implosion of the Cairngorm Event Dispatcher, the Front Controller, all of the Commands and all of the Delegates. The end result, is an MXML file (or files) that is the central hub of any project. The map is the first port of call for any new developers working on the project.
The Mate framework removes the need for the Singletons - the design pattern used in both Cairngorm and PureMVC. Instead, it uses its own caching solution to determine which objects have been instantiated and handles the flow of data between them.
Mate also uses the Event Map to support dependency injection. Instead of databinding elements from the Model to the appropriate View component, child-by-child, you let Injectors do the work for you. An Injector will insert the appropriate property into all instances of a particular component, without having to pass it through the component’s parental hierarchy.
If for some reason, the Event Map isn’t robust enough to handle the event chaining you require, you can instantiate your Controller (or Manager) classes with the dispatcher, so you can continue to propagate events from within the Controller back to the map.
Hopefully, you can already see how Mate seriously decreases the overhead of code that needs to be written.
What about Cairngorm?
Mate makes Cairngorm look rigid and verbose. The new framework does away with excessive class writing and the dependency on Singletons. Furthermore, Mate allows for any event handlers to have many responders, rather than mapping one Command to one Event as Cairngorm does.
Nevertheless, Mate will not replace Cairngorm.
Cairngorm has a well established place in enterprise Flex development. Apart from the fact that it is the framework that Adobe consultants advocate, it is also well suited to a large team. The implementation of the Command pattern allows for clear separation of logical work units, if albeit, at the cost of brevity.
The biggest problem facing Cairngorm is the apparent lack of documentation. It can be argued that Cairngorm is a highly flexible architecture that is poorly represented by a few meagre examples. Mate, on the other hand, has a plethora of documentation, examples and best practices on the AsFusion site, making it much easier for a developer to get on board.
The Event Map
Imagine a simple HR application that lists a collection of Employees. The user can switch to a form for editing, save the Employee, and then return to the listing.
Pseudo-code
When (Application Starts)
{
Dispatch (Load All Employees)
Dispatch (Goto List)
}
When (Load All Employees)
{
Load Employees from Remoting Layer
If (Success)
Set All Employees In the Model (result)
Else
Dispatch (Show Error)
}
When (Select Employee)
{
Set Current Employee (employee)
Dispatch (Goto Details)
}
When (Save Employee)
{
Save Employee in Remoting Layer (employee)
If (Success)
Dispatch (Goto List)
Else
Dispatch (Show Error)
}
In Mate, we could translate this to an event map like:
EventMap.mxml
<?xml version="1.0" encoding="utf-8"?>
<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/">
<!-- Flex APPLICATION COMPLETE -->
<EventHandlers type="{FlexEvent.APPLICATION_COMPLETE}">
<EventAnnouncer generator="{EmployeeEvent}" type="{EmployeeEvent.LOAD_ALL}" />
<EventAnnouncer generator="{NavigationEvent}" type="{NavigationEvent.GOTO_LIST}" />
</EventHandlers>
<!-- Employee LOAD_ALL -->
<EventHandlers type="{EmployeeEvent.LOAD_ALL}">
<RemoteObjectInvoker destination="ExampleDestination" method="LoadAllEmployees">
<resultHandlers>
<MethodInvoker generator="{EmployeeManager}" method="setAllEmployees" arguments="{resultObject}" />
</resultHandlers>
<faultHandlers>
<EventAnnouncer generator="{NavigationEvent}" type="{NavigationEvent.SHOW_ERROR}">
<Properties fault="{fault}" />
</EventAnnouncer>
</faultHandlers>
</RemoteObjectInvoker>
</EventHandlers>
<!-- Employee SELECT -->
<EventHandlers type="{EmployeeEvent.SELECT}">
<MethodInvoker generator="{EmployeeManager}" method="selectEmployee" arguments="{event.employee}" />
<EventAnnouncer generator="{NavigationEvent}" type="{NavigationEvent.GOTO_DETAILS}" />
</EventHandlers>
<!-- Employee SAVE -->
<EventHandlers type="{EmployeeEvent.SAVE}">
<RemoteObjectInvoker destination="ExampleDestination" method="SaveEmployee" arguments="{event.employee}">
<resultHandlers>
<EventAnnouncer generator="{NavigationEvent}" type="{NavigationEvent.GOTO_LIST}" />
</resultHandlers>
<faultHandlers>
<EventAnnouncer generator="{NavigationEvent}" type="{NavigationEvent.SHOW_ERROR}">
<Properties fault="{fault}" />
</EventAnnouncer>
</faultHandlers>
</RemoteObjectInvoker>
</EventHandlers>
</EventMap>
Note: we have ignored the handling of the view switching, or NavigationEvent, for the moment. We will come back to this later.
Immediately you can note some significant differences between the two frameworks. The above map essentially negates the need for:
- three Commands (LoadAllEmployees, SelectEmployee, SaveEmployee);
- one FrontController Singleton; and
- one Delegate (EmployeeDelegate)
Furthermore, had we chosen Cairngorm, how would we perform the two actions attached to the Employee SELECT Event?
We could have either:
- Dispatched the Navigation Event from within the SelectEmployeeCommand after we had set the current employee; or
- Dispatched the Navigation Event from within the View as we dispatched the Employee SELECT event (assuming we didn’t mind these two events to run asynchronously)
Either way, the series of events would be hidden until we went looking for them. The Event Map in Mate highlights the chain of events so that a developer can quickly and easily access the event flow within the application.
Bubbling Events
Mate removes the need to use the Cairngorm dispatcher Singleton by requesting that all events be allowed to bubble by default.
EmployeeEvent.as
package com.justinjmoses.examples.mate.event
{
import com.justinjmoses.examples.mate.vo.EmployeeVO;
import flash.events.Event;
public class EmployeeEvent extends Event
{
public static const LOAD_ALL:String = "loadAllEmployees";
public static const SELECT:String = "selectEmployee";
public static const SAVE:String = "saveEmployee";
public var employee:EmployeeVO;
public function EmployeeEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}
EmployeeEditForm.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Form xmlns:mx="http://www.adobe.com/2006/mxml" width="100%">
<mx:Script>
<![CDATA[
import com.justinjmoses.examples.mate.event.EmployeeEvent;
import com.justinjmoses.examples.mate.vo.EmployeeVO;
[Bindable]
public var employee:EmployeeVO;
/**
* Submit the form
*/
private function onSubmitClick(evt:MouseEvent):void
{
var empEvent:EmployeeEvent = new EmployeeEvent(EmployeeEvent.SAVE);
empEvent.employee = this.employee;
dispatchEvent(empEvent);
}
]]>
</mx:Script>
<mx:FormItem label="Name">
<mx:TextInput text="{employee.Name}" />
</mx:FormItem>
<mx:Button label="Submit" click="onSumbitClick(event)" />
</mx:Form>
If, for some reason, you need an event which doesn’t bubble, you can work around this using the Dispatcher tag.
Multiple Models
Unlike Cairngorm, Mate doesn’t rely on the Singleton pattern. It uses a caching system that remembers which objects have been instantiated and propagates data to them.
This means you aren’t forced to have one large Model class implementing ModelLocator, as with Cairngorm.
The common technique to is to break up your logic into various “Manager” classes, which contain both the properties that will make up parts of the Model, and some Controller logic.
EmployeeManager.as
public class EmployeeManager
{
[Bindable]
public var employees:ArrayCollection;
[Bindable]
public var currentEmployee:EmployeeVO;
public function setAllEmployees(employees:ArrayCollection):void
{
this.employees = employees;
}
public function selectEmployee(employee:EmployeeVO):void
{
this.currentEmployee = employee;
}
}
You could be forgiven for concluding that these Models in Mate violate MVC conventions by allowing the Model to behave as the Controller. The false premise here is that these Manager classes collectively comprise the Model. Rather, in Mate the Model is more abstract. The Model is a collection of properties from the various Managers that are Injected into the View.
Dependency Injection
Following on from our example, now think of how we are going to bind the results from our EmployeeManager class to the view.
Let’s say that our view hierarchy looks like this:
Application
|________MainUI (Panel)
|____________ContentContainer (VBox)
|_________________(Viewstack)
|______________________EmployeeList (Box)
|______________________EmployeeEditForm (Form)
Now, our Box containing the DataGrid is a component which looks like this:
EmployeeList.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import com.justinjmoses.examples.mate.vo.EmployeeVO;
import com.justinjmoses.examples.mate.event.EmployeeEvent;
import mx.collections.ArrayCollection;
[Bindable]
public var employees:ArrayCollection;
private function onEditClick(evt:MouseEvent):void
{
var editEvent:EmployeeEvent = new EmployeeEvent(EmployeeEvent.SELECT);
editEvent.employee = dataGrid.selectedItem as EmployeeVO;
dispatchEvent(editEvent);
}
]]>
</mx:Script>
<mx:DataGrid id="dataGrid" dataProvider="{employees}" />
<mx:Button label="Edit" click="onEditClick(event)" />
</mx:Box>
If we were writing this in Cairngorm, and we were lazy, we could simply modify the collection above to:
public var employees:ArrayCollection = MyModelLocator.getInstance().employees;
Of course we wouldn't do that. We’re implementing a framework to standardise our development to best practices after all. As such, we decouple the EmployeeList component from the Model by passing the employees list through the view hierarchy. To do this in Cairngorm means that both the MainUI component and ContentContainer parent would need to have an “employees” property, for them to pass it to EmployeeList. Heaven forbid you decide to go with an Array instead somewhere down the line; you’ll be left changing a lot of classes.
Mate, does away with this by injecting necessary properties into all components that require it. Another Event Map can be created with a list of classes and properties to inject, and this behaves as a Model.
Injector Map
<?xml version="1.0" encoding="utf-8"?>
<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/">
<Injectors target="{EmployeeDataGrid}" >
<PropertyInjector source="{EmployeeManager}" sourceKey="employees" targetKey="employees" />
</Injectors>
<Injectors target="{EmployeeEditForm}">
<PropertyInjector source="{EmployeeManager}" sourceKey="currentEmployee" targetKey="employee" />
</Injectors>
</EventMap>
From the map above, we can see that all instances of both EmployeeDataGrid and EmployeeEditForm will have the required properties from the various Managers injected into them.
Result Handling in the View
It could be argued that handling events in the View is a no-no. Nevertheless, Mate gives you the freedom to do so if you choose.
Switching the view via a Navigation Event is a fairly common occurrence in rich application development. In Cairngorm, you might be tempted to store your current view in the model, and bind some Viewstack to that. In Mate, we can let components in the View manage navigation themselves via the Listener tag, bypassing the Event Map. Yes, this will make those events less visible, but you may consider it a worthwhile trade.
ContentContainer.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" xmlns:view="com.justinjmoses.examples.mate.view.*" xmlns:mate="http://mate.asfusion.com/">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import com.justinjmoses.examples.mate.event.*;
]]>
</mx:Script>
<mate:Listener type="{NavigationEvent.GOTO_LIST}" receive="viewStack.selectedChild = dataGrid;" />
<mate:Listener type="{NavigationEvent.GOTO_DETAILS}" receive="viewStack.selectedChild = editForm;" />
<mx:ViewStack id="viewStack" resizeToContent="true">
<view:EmployeeDataGrid id="dataGrid" />
<view:EmployeeEditForm id="editForm" />
</mx:ViewStack>
</mx:VBox>
We can build on this using ResponseAnnouncers and ResponseHandlers. Taking the Editing Form from earlier, say we wanted to play a fancy animation in the form when a save was successful, before switching the view. We could change the Employee SAVE in the Event Map to:
EventMap.mxml
...
<!-- Employee SAVE -->
<EventHandlers type="{EmployeeEvent.SAVE}">
<RemoteObjectInvoker destination="ExampleDestination" method="SaveEmployee" arguments="{event.employee}">
<resultHandlers>
<ResponseAnnouncer type="{EmployeeEvent.SAVED}" />
</resultHandlers>
<faultHandlers>
<EventAnnouncer generator="{NavigationEvent}" type="{NavigationEvent.SHOW_ERROR}">
<Properties fault="{fault}" />
</EventAnnouncer>
</faultHandlers>
</RemoteObjectInvoker>
</EventHandlers>
...
Then, the onus is on the component that dispatched the Event to handle the response. See the modified EmployeeEditForm below:
EmployeeEditForm.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Form xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" xmlns:mate="http://mate.asfusion.com/">
<mx:Script>
<![CDATA[
import com.justinjmoses.examples.mate.event.NavigationEvent;
import mx.events.EffectEvent;
import com.justinjmoses.examples.mate.event.EmployeeEvent;
import com.justinjmoses.examples.mate.vo.EmployeeVO;
[Bindable]
public var employee:EmployeeVO;
/**
* Submit the form
*/
private function onSubmitClick(evt:MouseEvent):void
{
saveDispatcher.generateEvent();
}
/**
* When employee has been saved
*/
private function onSavedEmployee():void
{
animation.addEventListener(EffectEvent.EFFECT_END, onEffectPlayed, false, 0, true);
animation.play([this]);
}
/**
* When animation ends
*/
private function onEffectPlayed(evt:Event):void
{
dispatchEvent(new NavigationEvent(NavigationEvent.GOTO_LIST));
}
]]>
</mx:Script>
<!-- The SAVE event -->
<mate:Dispatcher id="saveDispatcher" generator="{EmployeeEvent}" type="{EmployeeEvent.SAVE}">
<mate:eventProperties>
<mate:EventProperties employee="{employee}" />
</mate:eventProperties>
<mate:responseHandlers>
<mate:ResponseHandler type="savedEmployee" response="onSavedEmployee()" />
</mate:responseHandlers>
</mate:Dispatcher>
<mx:Parallel id="animation">
<mx:Blur />
<mx:Fade alphaFrom="1.0" alphaTo="0.0" />
</mx:Parallel>
<mx:FormItem label="Name">
<mx:TextInput text="{employee.Name}" />
</mx:FormItem>
<mx:Button label="Submit" click="onSubmitClick(event)" />
</mx:Form>
This technique however, does have the unfortunate side effect of obscuring the event flow from the Event Map. However, you could consider this a fair concession to removing navigational clutter from the map.
Chaining Events
The MXML format of Mate can seem somewhat constricting compared to the AS version of Commands in Cairngorm. However, Mate is more flexible that it first appears.
A case in point: say you wanted to select the first Employee in the list after you’ve loaded them. We use a feature within the Event Map called Smart Objects. In fact, we are already been using them - event, resultObject and fault all are smart objects within the map.
The object we want is lastReturn, typically the last object returned from a MethodInvoker.
Our first step is to update our Manager’s setAllEmployees() method to return a valid Employee.
EmployeeManager.as
...
public function setAllEmployees(employees:ArrayCollection):EmployeeVO
{
this.employees = employees;
if (this.employees != null && this.employees.length > 0)
{
return this.employees.getItemAt(0) as EmployeeVO;
}
else
{
return null;
}
}
...
Secondly, we need add and bind the current employee to our DataGrid.
EmployeeDataGrid.mxml
...
[Bindable]
public var currentEmployee:EmployeeVO;
...
<mx:DataGrid id="dataGrid" selectedItem="{currentEmployee}" dataProvider="{employees}" />
...
Third, we need to inject the currentEmployee property into the DataGrid.
InjectorMap.mxml
...
<Injectors target="{EmployeeDataGrid}" >
...
<PropertyInjector source="{EmployeeManager}" sourceKey="currentEmployee" targetKey="currentEmployee" />
</Injectors>
...
Finally, we need to instruct the Event Map to announce a new SELECT Event within the LOAD_ALL handler using the returned employee from the setAllEmployees method.
EventMap.mxml
...
<!-- Employee LOAD_ALL -->
<EventHandlers type="{EmployeeEvent.LOAD_ALL}">
<RemoteObjectInvoker destination="ExampleDestination" method="LoadAllEmployees">
<resultHandlers>
<MethodInvoker generator="{EmployeeManager}" method="setAllEmployees" arguments="{resultObject }" />
<EventAnnouncer generator="{EmployeeEvent}" type="{EmployeeEvent.SELECT}">
<Properties employee="{lastReturn}" />
</EventAnnouncer>
</resultHandlers>
</RemoteObjectInvoker>
</EventHandlers>
...
Dispatching from within the Managers
As good as the framework is, there are times when the Event Map doesn’t quite cut the mustard. In these cases, events can be dispatched from the various Manager classes, and are simply handled by the Event Map. The drawback of course, is the obfuscation of the event flow.
For example, say the currentEmployee property in the EmployeeManager class had various methods working on it, and that any time it was updated we wanted an event to fire. Mate currently doesn’t support property watching natively in the framework, but hopefully it will be included in the future.
For now, you need to instantiate the Manager with a reference to the Mate dispatcher in order to propagate events back to the Event Map.
EmployeeManager.as
...
private var dispatcher:IEventDispatcher;
//New constructor that will be called by the ObjectBuilder in the Event Map
public function EmployeeManager(dispatcher:IEventDispatcher)
{
this.dispatcher = dispatcher;
//watch for property changes on the currentEmploytee
mx.binding.utils.ChangeWatcher.watch(this,"currentEmployee", onCurrentEmployeeChanged);
}
private function onCurrentEmployeeChanged(evt:PropertyChangeEvent):void
{
//dispatch some new event
this.dispatcher.dispatchEvent( ... );
}
...
Then, in the Event Map, you need to use the Mate ObjectBuilder tag to ensure the EmployeeManager instance has the event dispatcher.
EventMap.mxml
...
<EventHandlers type="{FlexEvent.PREINITIALIZE}">
<ObjectBuilder generator="{EmployeeManager}" constructorArguments="{scope.dispatcher}" />
</EventHandlers>
...
Generic Fault Handling
A recent addition to the Mate framework has been the ability to handle faults generically, rather than rewriting fault handling code incessantly.
Simply create a GenericFaultHandler class to perform some action every service call fault.
GenericFaultHandler.as
package com.justinjmoses.examples.mate.service
{
import mx.controls.Alert;
import mx.rpc.Fault;
public class GenericFaultHandler
{
public function handleFault(fault:Object):void
{
var f:Fault = fault as Fault;
Alert.show(f.faultCode + ": " + f.faultDetail);
}
}
}
Then ensure the map knows to reroute unhandled fault events to our class.
EventMap.mxml
...
<!-- Handle FAULTS -->
<EventHandlers type="{UnhandledFaultEvent.FAULT}">
<MethodInvoker generator="{GenericFaultHandler}" method="handleFault" arguments="{event.fault}" />
</EventHandlers>
...
Conclusions
Mate is a powerful MXML-based Flex framework, one which defies Cairngorm to be succinct.
It feels as though the creators took Cairngorm and streamlined it; simplified it.
What you have is an architecture that lends itself well to top-down design, without limiting the creativity of the developer.
The concept of an Event Map provides a clear and logical way of representing the control flow through the application. By leveraging dependency injection, Mate is able to significantly reduce code overhead and needless property passing. Its flexibility allows for events and actions to be seamlessly linked together; there’s even native event handling in the View if need be.
Cairngorm will continue to serve a significant role in Flex development, but Mate is here to stay. Any Flex developer worth their salt should seriously investigate this new framework to see what it can offer them.
Mate will not save the world, but it does make RIA development in Flex much more interesting.




Facebook Application Development
I'm just wondering if anything new is going to happen in the Flex world - especially with Flex 4 (or whatever you want to brainwash yourself in to calling it now) available?
I ask because Mate was covered last year in a series on this very website:
http://www.insideria.com/2008/12/frameworkquest-2008-part-5-mat.html
.. so it's not *that* new.
Save me reading, are you providing any new insight?
Cheers,
Chris
Ooh yeah, Mate is teh hotness.
Good overview of Mate. The worked examples make it nice and clear.
Cairngormers might be interested to check out these extremely cool bits of Mate: LocalEventMaps (localised event handling), easy use of the Presentation Model pattern, injecting to interfaces instead of concrete classes.
But, ** only use Mate if you need it. ** [1]
Mate event flow can be hard to debug. You may create more problems. Understand what your problems are, understand what a framework like Mate can do to make those easier, and apply as appropriate.
I.e. always apply YAGNI to yourself before applying frameworks...
Great cautionary discussion of IoC at http://martinfowler.com/articles/injection.html
[1] Using Cairngorm currently is not of itself a good reason to use Mate, perhaps you should ditch Cairngorm...
Nice Article. It is very useful to see the two frameworks side by side with examples. Thanks.
Romin.
I can't agree with that "It feels as though the creators took Cairngorm and streamlined it; simplified it." On the contrary, Cairngorm is more suitable for streamlined development, but this is on the cost of:
Mate doesn't cost that much, because Mate is a totally Flex solution and it takes into consideration the peculiarities of the Flex technology - it is not something taken from right out of the JEE list of patterns and applied directly into very different technology.
I'm still not convinced that you need a framework at all - Cairngorm or Mate, or whatever.
Check out this approach:
MVC Example without using any frameworks
MVC Example - Refactored - the same example but the MVC is applied on different levels of granularity, also the Model Adapter pattern has been introduced - it transforms a Model into Presentation Model.
@Chris Brind: No brainwashing needed. The Flex SDK is still going to be Flex 4. The Flex brand name isn't disappearing anytime soon. Flash Builder is the only thing with a name change because it is meant for more than Flex development. If you call yourself a Flex developer today, then you're still a Flex developer when Flex 4 comes out of beta. I can't believe I'm still correcting people on this one.
Back on topic:
The only thing I don't like about Mate is the requirement of bubbling events. The claim is that these events aren't framework specific, but they still feel to me like they're meant for a framework.
Mate already uses dependency injection to pass things to views. What I would like to see is something similar to find the components and listen to the events directly from the source rather than catching events that bubble up to the top. Seems like the obvious choice to make communication work the same way in both directions.
Like I said, though, other than that, I think Mate is great.
I'm not so sure this post is too accurate/useful.
1. IMO the EventMap example seems to fill the space of the FrontController. They are both a single point of mapping events to commands (or in Mate's case straight to a remote object or the like - eg mixing in command logic).
2. The author suggests the negated need for a delegate. Well in Cairngorm you aren't forced to use delegates. In fact they should only be used where it makes sense to use them. The fact many Cairngorm users always create delegates doesn't mean this is correct or enforced by the framework.
3. The author suggests the negation of the need for command classes in Mate is a good thing. In a large complex application this is crazy IMO. Encapsulating logic into command classes is incredibly useful.
I also agree with the comment of Vladimir. There is a good argument not to use these "MVC" frameworks at all. You dont need an "MVC" framework to write apps that follow the MVC pattern.
Now I'm not knocking Mate, but I'm not too confident it offers anything in the way of a clear advantage over Cairngorm/PureMVC or in fact a home-brew MVC based app.
It does offer a different solution and I'd love to hear from people who have used it in a large-ish application with a team of developers to find out how they got on with it.
From what I can make out, it would end up causing headaches in the long run!
Thanks for the nice article!
If you might have this code as a Flex project on your computer, would it be possible to share it?
Would be easier to figure out how all the pieces fit together.
If not, no problemo of course.
Kind regards,
Jochen
@jtgrassie
It's true that Cairngorm is a lot more flexible that the few examples around suggest.
I also agree that the Command pattern is overwhelmingly useful, particularly in large scale development.
My whole argument is that every Flex developer should at least look at Mate to understand how it works. The onus is on them to choose the right framework for their needs (or use their own, as other advocates suggest). At the very least, Mate demonstrates a novel way of using the Flex framework. That, in of itself, is worth the amount of time required to investigate it.
@Jochen
Unfortunately I don't have the full example.
However, you can see a good range of lightweight examples on the asfusion site: http://mate.asfusion.com/page/examples
@Justin, Thanks so much for putting this article together. I just wanted to mention that it is not necessary to add Mate tags in your views. We have a tag called ListenerInjector that replaces the Listener tag and a CallBack that replaces in some way the Responses tag.
Having the views clean of Mate tags makes the framework less intrusive.
For more info you can read the following post:
http://mate.asfusion.com/news/what-s-new-in-0-8-5
Sorry if the next comment is going to be too negative...
I just don't understand the fuzz about Mate. I come from a springactionscript / cairngorm background and i am trying Mate now (cause everyone seems to like it...)
It looked really promising, but to be honest i like cairngorm / prana much better. The event map is irritating me a lot because i need to remember too much. targetKeys sourceKeys event. etc. Al of those are strings... no code completion and refactoring is possible without manual labour makes this really frustrating.
for example in the next code (Tim Hoff example):
<!-- Search for Videos -->
<EventHandlers type="{ SearchEvent.SEARCH_VIDEOS }">
<MethodInvoker generator="{ VideosManager }" method="initializeSearch" arguments="{ event }"/>
<google:VideoSearch>
<Properties searchString="{ event.searchString }" startValue="{ event.searchStartIndex }" language="{ event.language }"/>
<google:resultHandlers>
<MethodInvoker generator="{ VideosManager }" method="searchVideosResult" arguments="{ currentEvent.data }"/>
<MethodInvoker generator="{ VideosPresentationModel }" method="showSearchResults"/>
</google:resultHandlers>
</google:VideoSearch>
</EventHandlers>
i have 10! places where i dont have code completion and where you get problems with refactorings.
(count them, and dont let you be fooled by stuff like searchString="{ event.searchString }" that one has 2 places where i have to manualy remember property names:
1) searchString
2) event.searchString
Also i prefer coding for logic and using markup for view stuff. But that is just preference.
in cairngorm i can dispatch a simple event in 1 line, map that event on a command in one line in the front controller and if you know how to abstract things a command can be really short.... Just make a base command that does logging , handle faults in a generic manner etc... Anyway, why do people hate commands so badly? they have:
- 1 way to do things which is nice and easy
- encapsulate a functionality of your application that is very reusable
- can easily be extended to build undo functionality
- can be generated as they all have the same structure. So it can acually be really fast.
I do agree that the singletons in views in cairngorm are ugly, but have a look at springactionscript and autowiring and the singetons are removed from your views. let the framework manage the lifecycle of models just like mate. tada!
people these days are going to extreme length talking about reusing views and non intrusive frameworks especially when talking about views. I never reuse views, how many times do u? Honestly? And how many times do you reuse logic? A lot more right? Well, then presentation models that have intrusive framework code like (dispatcher code of mate) seem more of a problem to me.
Anyway, i though i found the ultimate framework as i beleived the hype. There are many frameworks i like better. Somehow really nice frameworks like parsley, springactionscript and swiz don't pick up as much momentum as mate which is in my opinion really ashame.
cheers!
Arnoud