Filed under: Uncategorized | Tags: actionScript, cairngorm, dependency injection, flex, inversion of control, Maté, mvc, mxml, PureMVC
Notes
- the code samples and sample application utilized Flex 4 SDK
- I am using a patched version of Mate to accommodate the Flex 4 SDK
- I will post further updates to this post so stay tuned
- the sample application is UGLY, so don’t expect anything great here folks. Just enter some text in both text fields and hit save. Tada. It gets sent to two hidden labels.
- you can download the sample application here – link
Goals
As of late I have been quite obsessive about finding a solution in which an application’s MVC constituents could be highly decoupled. Some of the requirements in this solution are:
- view classes have no knowledge of UX logic (no dispatching of CairngormEvents)
- view classes have no knowledge of Model objects nor {binding} to objects outside their local members
- view classes are ignorant of any mediators wrapping them
- command classes are ignorant of any mediators dispatching any UX logic events
- command classes have no knowledge of Model objects outside of data payloads riding in on execution parameters
- avoiding Singletons where possible
Don’t you just love lists? I do
This at first sound very restrictive especially to those of us who are long-time Cairngorm users. It is quite easy to {bind} a view to a model class and be done with it. This is great in mocking up prototypes quickly but is a shortcut that leads to plenty of headaches later on. It’s quite easy to perform UX logic inside a Command class and then directly wire into a ModelLocator. Again, this proves to be a pain if you are looking to do some sort of unit testing or want to decouple from your Model classes.
So let’s look at a few good things that each of these frameworks provide such that we can pick out the best and discard the rest.
Cairngorm
- Command pattern – being able to abstract out UX logic into commands is just great. It adheres to the MVC paradigm so long as we are able to decouple the constituents.
PureMVC
- Mediator pattern – this allows us to accomplish points 1 & 2 above in the requirements. It does mean that mediators are obviously knowledgeable about their views but its a one-way coupling issue.
Maté
- Dependency Injection – the ultimate solution in decoupling all MVC actors. Maté’s unique binding solution for DI is great in that we needn’t have to implement anything aside from the Injector mechanisms. This affords us the ability to also have multiple DI maps for various scenarios, whether that be UI testing, unit testing or whatever.
- EventMaps – In a general sense the EventMap is a great way to delegate the task of doing all the Controller logic that normally we have to do ourselves in Cairngorm or PureMVC.
So there you have it: An outline of how I plan to use these 3 frameworks to build a highly decoupled app in which all our MVC actors are basically plug n’ play classes. Cool sounding eh? Ok, now that that is out of the way I need to explain a few specifics with respect to the Command and Mediator pattern and how I use them.
Command classes
Using an out of the box Cairngorm ICommand is a bit restrictive in this solution so we are going to borrow the interface and change it up a bit. Rather than this:
execute (event:CairngormEvent):void
we need something a bit more loose like so:
execute (params:Object):void
In this, we are simply accommodating some of the restrictive mechanisms found in how Maté handles the event system. You could wire it in many ways but for the most direct route let’s stick with this. The other thing we need to do is have our Command classes extend event dispatcher so that we can signal back to Maté that either the response logic or fault logic has commenced. So here is a sample of how the IResponder portion works in these commands:
result (data:Object):void
{
//assuming your response from some service,
//say an XML response that needs massaging to an AS3 Value Object
var vo:SomeValueObject = data;
var resultEvt:DynamicEvent = new DynamicEvent("result");
resultEvt.data = vo;
dispatchEvent(resultEvt);
}
fault (info:Object):void
{
var faultEvt:DynamicEvent = new DynamicEvent("fault");
faultEvt.data = vo;
dispatchEvent(faultEvt);
}
So this should be roughly inline with what most Cairngorm users do on a regular basis.
Mediator classes
It’s not like PureMVC invented the mediator pattern, but it certainly brought the valued pattern to light to many Flex developers. There are no particular implementations from PureMVC or anywhere else, this is just my spin on it:
Views should implement a simple marker interface called IMediatorClient. That’s it. If you are using Flex 4 SDK, then remember currently code hinting will not work when typing “interface” in your MXML tag. It will compile just fine. At least it did for me.
Mediators happen to implement the following interface:
public interface IMediator
{
function get target ():IMediatorClient;
function registerTarget (target:IMediatorClient):void;
}
Now we need keep in mind a few Maté specific things here. Because Maté happens to leverage the display list and some of the inner workings of the Flex system manager we have three choice in how Maté gets wind of our events.
- dispatch bubbling events from our IMediatorClient (because all views will be IEventDispatchers by their very nature)
- wire in a specific Dispatcher from Maté (this means bringing in Maté specific code into our pristine code. no….)
- find some other solution that probably entails a central event dispatcher that then wires into an EventMap
Obviously solution #1 is the most unobtrusive and easiest for OCD folks (like me) to deal with. Let’s stick with that for now. Besides, a bubbles event is not such a bad thing is it? Just make sure that you are using some unique event types otherwise you might trigger unexpected handlers elsewhere in your application.
So let’s see how we wire these puppies up into Maté.
Maté wirings
First up is the what I am calling a Mediator Map. Simply put it is a way to wrap your IMediatorClient views into IMediators without specifically having the wiring code in anything but Maté. Note that I am doing this in Flex 4 SDK and thus requires the use of the declarations tag.
<?xml version="1.0" encoding="utf-8"?>
<mate:EventMap
xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo" xmlns:mate="http://mate.asfusion.com/">
<fx:Script>
<![CDATA[
import app.view.*;
import app.view.mediators.*;
]]>
</fx:Script>
<fx:Declarations>
<mate:Injectors target="{SampleIMediatorClient}" debug="true">
<mate:MethodInvoker generator="{SampleIMediator}" method="registerTarget"
arguments {event.injectorTarget}"/>
</mate:Injectors>
</fx:Declarations>
</mate:EventMap>
So this MediatorMap would be placed on your Application level class. Simple enough right? The cool thing is that this autowires a view to a mediator when the view gets attached to the display list. And because Maté is in charge of caching the instances it creates, you will soon see that the mediator can be referenced in the DI map below.
Dependency Injection map
So this next map is where we are basically injecting model classes into mediators which in turn affect changes on the views through whatever logic you so desire. I like using the IDataRenderer interface alot as it is easy to remember. Check it out:
<?xml version="1.0" encoding="utf-8"?>
<mate:EventMap
xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" xmlns:mate="http://mate.asfusion.com/">
<fx:Script>
<![CDATA[
import app.model.*;
import app.view.*;
import app.view.mediators.*;
]]>
</fx:Script>
<fx:Declarations>
<mate:Injectors target="{CurrentUserViewMediator}">
<mate:PropertyInjector targetKey="data" source="{UsersManager}" sourceKey="currentUser"/>
</mate:Injectors>
</fx:Declarations>
</mate:EventMap>
So all this does is say, when we make a change to the currentUser on the UsersManager class, we want to let the CurrentUserViewMediator know about the change. Maté handles the binding mechanisms internally. Lastly I need to show you how the command classes are wired into the EventMap.
EventHandlerMap & Commands
I had written an earlier post on this but I will post it here too. So this is kinda the tricky part about Cairngorm and Mate playing well together. Remember we had to make our Commands dispatch events? Well here is why. The AsyncCommandInvoker class in Mate expects to hook into events of specific types. Since our commands implement IResponder, why not keep it simple and just have it expect the same from the event types.
<?xml version="1.0" encoding="utf-8"?>
<mate:EventMap
xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" xmlns:mate="http://mate.asfusion.com/">
<fx:Script>
<![CDATA[
import app.controller.commands.*;
import app.model.*;
import app.view.*;
import app.view.mediators.*;
import com.adobe.cairngorm.control.*;
import mx.events.*;
]]>
</fx:Script>
<fx:Declarations>
<mate:EventHandlers type="saveUser">
<mate:AsyncCommandInvoker generator="{SaveUserCommand}" successType="result">
<mate:successHandlers>
<mate:PropertySetter generator="{UsersManager}" targetKey="currentUser"
source="{scope.currentEvent.data}"/>
</mate:successHandlers>
</mate:AsyncCommandInvoker>
</mate:EventHandlers>
</fx:Declarations>
</mate:EventMap>
Notice the successType in the AsyncCommandInvoker. This is that event we dispatched from the result method on the command. Similarly there is a faultType which we would dispatch “fault” there. So one question you might have is, “where is the saveUser event type getting dispatched?”. So in this example, I had my mediator wrapping the EditUserView tie into a save button click event. Then it dispatched an event from the view that bubbled up with the type saveUser.
Conclusion
Well there you have it, a quick mash up of how to combine the best elements from the various MVC frameworks along with some cool IoC/DI wiring from Maté. Is it perfect? Far from it. It’s funny how these things come in spurts. I hadn’t made any progress for a long time, reading up on things like Parsley, Swiz, Spring Actionscript and RobotLegs only to find that I was dissatisfied. To tell the truth I didn’t even give these other framework a chance. I was lazy and didn’t feel like learning something new when I knew that I could do it pretty much with Mate, Cairngorm and PureMVC.
I am psyched to try this in a bigger application at some point. I do have a few reservations regarding Mate, specifically with respect to cached instances and all the behind-the-scenes {binding} that takes place. How does this affect performance and memory? The other big issues is that debugging this is a pain. I haven’t figured out all the intricacies of Mate and if a problem occurs outside of your main actors, debugging gets difficult. Lastly, the idea of Singletons have been removed from your MVC actors but isn’t this then just passed on to Mate in some sense? Well not to fret but just some things to think about.
Let me know your thoughts and ideas.
Filed under: Uncategorized | Tags: actionScript, cairngorm, dependency injection, development, flex, inversion of control, Maté, mvc, PureMVC
First off, note the word “paradigm” rather than the more commonly used word “framework”. As a self proclaimed pragmatist, the word paradigm seems more fitting in a world where no one shoe fits all. Aren’t you tired of hearing the old debate of “which MVC framework is best”? I am tired of the whole Cairngorm, PureMVC, Maté, Swiz, blah blah blah…. The dealo is that they all offer some strong solutions for common problems. Certainly having NO MVC infrastructure in your application is a poor choice. I have indeed been on a quest to find some solution in which I could utilize all the best from each library while leaving behind the bad.
Now I should preface this by saying I have no formal training in Computer Science. I have been on a quest for a good dependency injection solution for a long time not knowing that was what it was called. Besides, what’s in a name? Does dependency injection or inversion of control really convey to the layperson the idea of wiring up an application? I think I am fairly smart and I didn’t understand it even after reading Wikipedia on the subject. To finish up here, let me compose a written goal(s) of what this post is all about and then I will dive into each point where applicable. Some of these may be common knowledge but are still worth pointing out (pardon the “no-duh” points):
- hereinafter the word “framework” will refer to existing MVC constructs such as Cairngorm, PureMVC, Maté, etc.
- hereinafter the word “wiring” will refer to either an existing or proposed IoC/DI construct such as Spring Actionscript (formerly known as Prana), Maté’s Injector logic, etc.
- User eXperience is hereinafter referred to as UX. Any and all executable logic, whether triggered by user interaction or through subsequent data manipulation is considered UX.
- application MVC constituents should be highly decoupled in the following manner:
- view classes will be ignorant of any UX logic associated with their interactivity. This will be accomplished either by a wiring mechanism similar to Maté’s EventHandlers in its EventMaps or PureMVC’s Mediators.
- controller/command classes should function independently of one another such that particular UXs can be assembled via the wiring in a building block fashion.
- data/model classes are to avoid ModelLocator implementations. This will entail less {binding} and more verbose wiring logic. This will accommodate modular application structures where Singletons are problematic.
- Leveraging the event-driven nature of the Flash Player is ideal.
- A solution that is Flex-agnostic is ideal.
- A solution that can either take an XML or MXML map is ideal. Having the option to “compile” the wiring is nice in that it maps much like the DI of Maté.
So there are a few goals I have in mind. Obviously existing frameworks and wiring solutions have tackled some of these but I feel that they are mostly intrusive. People use the term “boilerplate” code in reference to Cairngorm but I’d rather say that Cairngorm give you enough rope to hang yourself with. People claim that PureMVC’s mediator implementation makes for more classes but I’d rather say that it is simply the price you pay for decoupling your views from your UX logic. People say Maté is alot of smoke and mirrors but I’d rather say the idea of IoC is new to Flex developers that we haven’t readily accepted the fact that it works.
If you would like to see some of the work I am doing on this, you can check out some of the Mediator/Maté hybrid mashup stuff I am working on here – http://subversion.assembla.com/svn/as3mediatorlib/trunk.
Please sound off and if you are interested in working on a solution please contact me. Thanks.
Filed under: Uncategorized
![]()
Palo Duro Canyon is the second biggest canyon network in America. It pales in comparison to the Grand Canyon however, due to its smaller size it is quite a bit more accessible for a multitude of activities. More info can be had here – link
A few things to note. The Texas Panhandle is pretty darn flat. Not quite as flat as some areas of Southwest Kansas but pretty close. To an outsider, growing up in Amarillo, TX might seem like a boring time to a youngster. And to some that may be so. But as a kid, my folks impressed upon me the beauty of the outdoors and introduced me to PDC at an early age. It offers breathtaking vistas, extensive mountain biking and hiking trails and several camping areas for tent and RV campers alike. I have logged many hours biking and hiking PDC.
The real reason I wanted to post about this is to not only tell you how awesome PDCanyon is, but I want you to see it in 3D. Check out this 360 cam with several views of my favorite place in the world – link
Filed under: Uncategorized
If someone asked me, ” as a child, what was your favorite toy?”, I would have to respond, “my Legos”. Legos are the coolest toys. I probably logged thousands of hours over my childhood making cranes with my dad or spaceships or giant robots. In fact, being in my thirties, I still utilize my legos to make prototype designs and to get an idea about scale.
Anyway here is a video and an instructable on how do build a lego combination safe.
instructable – link
Filed under: Uncategorized | Tags: actionScript, cocoa touch, comparison, development, iPhone, note to self, objective-c, tips, xcode
[note to self]
Just some things I am learning along the way while teaching myself Objective-C and iPhone development. Seeing existing code is rather easy to understand in a general sense but the syntax is a tad whacky looking at this point. I will continue to add to this as I find more translations.
variables:
NSString * someString = @"foo";
=
var someString:String = "foo";
casting:
NSObject *someObject = //pretend I know how to say new(); NSString *castedAsString = (NSString *)someObject;
=
var someObject:Object = {};
var castedAsString:String = String(someObject);
strings:
Strings come in several varieties in Objective-C. There are NSString, NSMutableString and then the C varient char. There are probably others I have yet to discover (CSString?). Since most of what I have seen utilizes NSString, I will stick to that unless otherwise noted.
combining string values
NSString *firstString = @"foo"; NSString *secondString = @"bar"; firstString = [firstString stringByAppendingString:secondString]; //should trace out as "foobar"
=
var firstString:String = "foo"; var secondString:String = "bar"; firstString = firstString + secondString; //wow AS3 is very simple when working with strings
class & instance methods:
+someMethodDefinition = static public function
-someMethodDefinition = public function (instance function)
method calling:
NSString * someString = @"foo"; NSArray * someArray = [someString someNSStringMethodThatReturnsAnArray];
=
var someString:String = "foo"; var someArray:Array = someString.someStringFunctionThatReturnsAnArray(); //kinda made this up since I don't understand method arguments in Objective-C yet.
more to come…
Filed under: Uncategorized | Tags: consulting, development, flex, iPhone, java, resume, technology
Given that the hype over Flex has kind of reached its apex I think its high time I start broadening my skill sets. I am not saying the Flex is a “done” technology, I am simply stating that Flex has reached a satisfying market share for RIA development and that the honeymoon is over.
So what does a Sr. Flex Developer decide to pick? Well iPhone development is all the rage so that’s a no-brainer. But then again that is just another client-side technology. Java and ColdFusion are still hot technologies. Going with either one would be a good choice (or both for that matter). I know some PHP and MySQL but I am not sure what the opportunity costs are for continuing to develop those skills are. I don’t really see myself doing too much in the way of web design nor do I see myself as a DBA. I might still tackle those when I can do so without incurring significant opportunity costs.
This post is simply to post my thoughts and maybe get some community feedback. Thoughts, comments, questions, concerns? Let’s hear ‘em.
Filed under: Uncategorized | Tags: actionScript, AIR, cairngorm, consulting, development, flash, flex, Maté, PureMVC, resume, RIA
posted an update to my resume – http://jwopitz.wordpress.com/resume
Filed under: Uncategorized | Tags: actionScript, development, math, note to self, tips
[BEST]
*however it does throw a compiler warning 3590: int used where a Boolean value was expected. The expression will be type coerced to Boolean.
var isOdd:Boolean = numberToCheck & 1;
[BETTER]
Math.round( Math.random() ) == 0 ? 1 : -1;
[GOOD]
odd or even = Math.round(Math.random() * 100) % 2 == 0 ? "even" : "odd";
-1 or 1 = Math.round(Math.random() * 100) % 2 == 0 ? 1 :- 1;
Filed under: actionScript, cairngorm, development, flex, frameworks | Tags: actionScript, cairngorm, development, flex, Maté, PureMVC, tips
So I am on the quest to create a hybrid MVC mini-framework that combines some of the best elements of Cairngorm, PureMVC and Maté. The idea is to use the Command pattern from Cairngorm (because I like all my service/UX logic to be placed there and the EventMap’s dependencies on binding and MXML seem limiting), the Mediator pattern from PureMVC (which unclutters and decouples the views) and the EventMap and Injection logic from Maté (which will help to further decouple some of the command=>model logic).
Keep in mind I have only really been working with Maté for a couple of months and have only dived into actually understanding it in the last week or so. So if you know of a better way of doing what I am trying to accomplish, please let me know and I can update the article.
This will mostly address how to decouple some of that command => model logic. This means we are striving to get the command classes as model-agnostic as possible. It also means there needs to be a slight modification to the current CairngormCommand structure. We will keep the CairngormEvent in use because its data payload is useful in sending data back and forth from the event dispatchers/listeners. In order for a command to send info back to a listener, it will need to extend EventDispatcher. Then depending on the result or fault logic, it can dispatch an appropriate event with a data payload. Here is some stub code:
public class SampleMateFriendlyCommand extends EventDispatcher implements IResponder
{
public function execute (evt:Event):void
{
//the function signature could be anything including execute (... args)
//notice I am not implementing the ICommand interface as I want to have more flexibility
}
public function result (data:Object):void
{
//parse data object if needed.
var evt:CairngormEvent = new CairngormEvent("success");
evt.data = parsedResultDataObject;
dispatchEvent(evt);
}
public function fault (info:Object):void
{
//parse info object if needed.
var evt:CairngormEvent = new CairngormEvent("fault");
evt.data = parsedFaultInfoObject;
dispatchEvent(evt);
}
}
I like the Command pattern because I think of it in a military sense. You issue a command to a soldier and that soldier executes the command, then generally reports back. So this is akin to that analogy. Next we need to see how to get the data back to the EventMap in order to wire the result/fault data into the appropriate places. I tinkered with this for quite some time before stumbling upon this solution. The Maté API docs are decent but fail to cover much beyond explaining the self explanatory. I really hope they work on their API docs and really flesh out the information.
<mate:EventHandlers id="applicationCompleteHandler" type="{AppEvent.SAMPLE_MATE_COMMAND}" debug="true">
<mate:AsyncCommandInvoker generator="{SampleMateFriendlyCommand}" successType="result">
<mate:successHandlers>
<mate:PropertySetter generator="{SomeModelObject}" targetKey="data" source="{scope.currentEvent.data}"/>
</mate:successHandlers>
</mate:AsyncCommandInvoker>
</mate:EventHandlers>
The AsyncCommandInvoker allows you to specify the event type that will trigger the successHandlers or the faultHandlers. Accessing the data payload for the result or success event is done using scope.currentEvent.data. Again I must reiterate that I stumbled upon this find because there was no documentation that I could find to support what I was trying to do.
The cool thing about this is that you have now freed up your commands so that they needn’t know about any specific model objects. That is unless you really want to strongly type your result data objects. This freedom allows for better testing as you can simply wire up a testing event map if you want to unit test.
Next up will be trying to wire mediators and their respective views into the event map.
Filed under: actionScript, components, development, flex, tutorial | Tags: actionScript, components, development, flex, mxml, tips
Assume that you are creating a component in MXML such as some multi-state cell renderer or something that implements IDataRenderer.
All mx.core.Container subclasses have a convenient little event hook called dataChange. Anytime you set a value to the data property, the component dispatches an event of type FlexEvent.DATA_CHANGE. To hook into this you simple access it in MXML like so:
<mx:VBox dataChange="do something"/>
With this in mind I suggest that those wishing to do more complex visual changes to their component that {binding} cannot address do the following:
- create a flag to indicate a data change has occured:
private var bDataChange:Boolean = false;
- connect the dataChange hook to the flag:
<mx:VBox dataChange="bDataChange = true;"/>
- address the data change in the call to update the display list:
override protected function updateDisplayList (unscaledWidth:Number, unscaledHeight:Number):void { super.updateDisplayList(unscaledWidth, unscaledHeight); if (bDataChange) { bDataChange = false; //do your custom logic here } }
The nice bit about this is that you are doing the necessary logic to update the display list when it makes sense to do so (via the already established update framework in the Flex API). It also reduces the need to override the getter/setter for the data property.
