Here is an index of the Parsley posts and examples with source that you will find:
Why we like Parsley: This note.
Parsley Basic Concepts: http://artinflex.blogspot.com/2010/09/quick-dive-into-parsley-parsleys-basic.html
Basic Injection Example: http://artinflex.blogspot.com/2010/09/quick-dive-into-parsley-basic-injection.html
Basic Messaging Example: http://artinflex.blogspot.com/2010/09/quick-dive-into-parsley-basic-messaging.html
Basic Messaging with Flex Events Example: http://artinflex.blogspot.com/2010/09/quick-dive-into-parsley-messaging-with.html
Nested Contexts & Object lifecycle methods: http://artinflex.blogspot.com/2010/09/quick-dive-into-parsley-nested-contexts.html
Decoupled Bindings: http://artinflex.blogspot.com/2010/10/quick-dive-into-parsley-decoupled.html
Dynamic Commands & Dynamic Objects: http://artinflex.blogspot.com/2010/10/quick-dive-into-parsley-dynamic-command.html
Automatic Component Wiring: http://artinflex.blogspot.com/2010/10/quick-dive-into-parsley-automatic.html
Fast Inject (Injection without Reflection): http://artinflex.blogspot.com/2010/11/quick-dive-into-parsley-fast-inject.html
Presentation Model in Parsley (MessageInterceptor): http://artinflex.blogspot.com/2010/11/presentation-model-implemented-in.html
Presentation Model with multiple forms in Parsley: http://artinflex.blogspot.com/2010/12/presentation-model-with-multiple-forms.html
A little background on how and why we chose to use Parsley in our projects.
Flex some years back and fell in love with it. As usual, the quest for finding better ways of doing things is always on, and as projects grow in size this becomes even more important. A while back I heard about the MVC Architecture pattern, and in larger projects this makes sense. In brief, MVC is a software engineering design pattern, that involves separating the Model, the View, and the Controller, with the goal of being able to develop, deploy, and test your Components individually (generally called decoupling). You can get a much more detail explanation of the MVC concept in Wikipedia (http://en.wikipedia.org/wiki/Model View Controller), but in a very simplified fashion, the View is the collection of User Interface elements, the Model is the collection of classes that hold and manipulate your data, and the Controller is the collection of classes that receive input and proceed to either make calls to Model Classes, or Services to load data into the Model. The idea of separating all three is actually a good idea, you will be surprised how much time you will save by doing this as projects grow. The main goal is to decouple your objects. The idea is that every object should do its own thing, and only its own thing. Decoupled objects benefit from being more easily reused in other projects or even within the same project because they are not tied to a specific implementation, also they are more easily tested individually (Unit Testing), since you (the developer) makes sure that it does what it is supposed to do, regardless of where or how it is implemented. The drawback of highly decouple applications is that it's a bit harder to follow the whole application logic, as it's no longer obvious. Simply put; your application becomes more "event driven" and easily become more asynchronous, which leads to having no control of when exactly the methods will be called.
Now MVC is a pattern, not a framework. There are multiple frameworks that have been created to help you follow the MVC pattern, and one of the most known in the world of Flex is called Cairngorm (http://sourceforge.net/adobe/cairngorm/home/). Cairngorm is one of the original frameworks aimed to assist the developer in following the MVC pattern. You do not need a specific framework to do so, but they do help. When I started using Cairngorm, I really enjoyed the benefit of using it as the projects grew in size. Cairngorm is one of the most popular MVC frameworks for Flex, probably because it is officially back by Adobe, and it's been around longer.
A lot of people will bash Cairngorm for some of the ways it handles things, particularly for its implementation of the ModelLocator. Cairngorm uses Singletons, a single instance of a Class (which could also be called a Global Variable), to hold some of its objects. Regardless of its "incorrect" way of implementing things, it's actually useful. Cairngorm promotes the use of a specific structure, which makes team collaboration easier, and as much as people could call its ModelLocator an atrocity, it's actually handy in many cases.
A simple example: Let's say that you have an application that allows users to Log In. But being logged in is not a requirement in every area of your application. Once the user has logged in, you probably want to hold the state that the user is logged in and the session id. Now, you add some feature that requires the user being logged in, so the component has to check if the user is logged in before it lets the user access that feature. Using regular dependency injection, involves passing the logged in status information all over the place, just in case one of the subcomponents requires access to that information, even if the parent's don't really care. With Cairngorm's ModelLocator, that's not the case, because if a subcomponent needs the logged in status, it doesn't need to get it from its parent, it can just reach and grab it. This will uncouple all the component's that don't need this information from this particular implementation, which is good, cause you can reused them more easily. They don't need to carry data around that they don't need, simply because one of their children or grandchildren might need it.
So if this is good, why do people "hate" it so much? Well, the problem is with the "reach and grab it", particularly with the "reach". Although some decoupling is accomplished using Cairngorm, the component's that needs to "reach" now gets coupled and tied to that particular implementation of the ModelLocator, and doing unit testing become much more difficult.
That said, the main reasons we decide to leave Cairngorm follow:
- Cairngorm is heavily dependent on binding, which is useful in many cases but can get annoying. Under Cairngorm , the Controller makes a Service call, and feeds the Model through Commands. But let's say that the user request some data, and when the service call returns it turns out that there are no records that match that search, so nothing will be added to the Model. Since the View is bound to the Model, the view will usually refresh when new data arrives, but if there is no data added, well it won't refresh, there is no change. It's a nice feature to let the user know that no data was found, but the view will simply not know this. You could of course create a popup from the Command letting the user know that that no data was found, or you could set a flag in the model that the View is "watching" to raise the issue and display the message. The popup approach I don't like because you are moving elements of the View to the Command which breaks the pattern, but more importantly, still the view doesn't know that there is no more data and can't adjust because of it. Setting a flag would be the one "correct" approach, but this adds a lot of logic for a simple thing. Why a lot of logic? Well, first you need to add a property change watcher (ChangeWatcher.watch()). But property change watchers in Flex lead to memory leaks if you don't remove them before the item is destroyed (ChangeWatcher.unwatch()). But Flex doesn't have "Destroyers" that get called before your object get's destroyed. Since it's a view, you can use the removedFromStage event that would be called when your item is removed. Great!... Right?... Wrong. See the Flex framework occasionally re-parents view components (for example when scrollbars are added) which will trigger the removedFromStage event. So, now you are also force to monitor the addedToStage event to set the watchers back up in case they got removed during a re-parenting process. Although this would be a "correct" approach, I simply think it's way too much of a hassle for something that simple. You could set up an event listener tied to the Model, but you still need to remove the event listeners when your view is being removed, same long approach as with the flag, and again you couple your view even more to that model. I, of course, hacked my way around it, setting a callback function in the event that triggers the command so that the command can notify the view directly for things such as this. Some might argue that this breaks the MVC pattern, but there is no ONE way of implementing MVC, and it certainly accomplishes the decoupling goal in a much simpler fashion. The only really un-debatable problem with my quick hack is that only the view that generates the event that called the command will get the message back from the command.
- Cairngorm's limited decoupled messaging system. The second really important issue with Cairngorm from my point of view is somewhat related to issue #1. Cairngorm's decoupled messaging system is aimed towards executing Commands. All other messaging is "supposed" to be done through either binding or Flex/Flash Events, and although binding is messaging, binding is not the best way to accomplish ALL messaging. Besides, Binding involves coupling, which is the opposite of the original goal. You can use Flex's event mechanism, but that also means that you will go back to coupling. Flex's Binding and Event messaging mechanism involves that you must listen to a specific object. Although Cairngorm's messaging is aimed to aid in some issues, it is simply too shortsighted, it's basically a one way road.
- The Singleton. I know I said it comes in handy, but it can become a problem. Since the Model is a Singleton, it is shared by the whole application. Sometimes you want to have SubModels. Model's that are shared only in a section (context) of you app. Or you have an application that allows the user to edit a customer's data, but suddenly the user needs to edit another customer's data, but the user doesn't don't want to close the window and "save" the changes to the other customer just yet, just open a new Customer window to work in. Basically an MDI (Multiple Document Interface) app. You need two models that are identical, but hold different data views. Cairngorm will not help you here, since the models are global. They are not within a specific scope. You of course, can find the way around that, but it's on your own.
- Lack of Modularity. Cairngorm is very friendly with RSL's, but it's not friendly with Modules. You can use Modules, but it's somewhat limited. This is related somewhat to issue #3. Since Models and the FrontController are implemented with Singletons. There is a way to make it work with modules, but keep in mind that is not how it was designed to work. You can read about it here.
So all that said, I still think Cairngorm will help you with non-small projects, but there are "better" ways.
So I'll explain what "better" means to us. Ideally it must be:
- Flexible. There is no one absolute unique "right" way of doing things. Patters are good as long as they help you accomplish your goals. When they start getting in the way, it's time to chose a different pattern or at least modify it. They guys from the very successful Flick site have a saying that they "generally try do the dumbest thing that will work first." Sometimes elegant solutions are not the best way of actually getting things done.
- Have a powerful Decouple Messaging System. Way beyond what Cairngorm does. Messages should be able to be sent anywhere to anywhere in a decoupled way. A plus is if the can be limited within a specific context (scope).
- Allow for easily integration with Flex Modules. This is a BIG important issue for us.
- Aid in decoupling. A framework that aids with achieving Inversion Of Control (IOC).
- Simplifies Dependency Injection. You don't need a framework to use Dependency Injection. Actually DI is available by default in ActionScript, or just about any OO language. The issue with DI without the assistance of a framework is that you will have to manually carry all objects around, which will work against decoupling the app. The idea is to have the framework manage the DI, so I as the developer don't have to, achieving a much higher level of decoupling. No singletons in the model, unless you actually want one.
- Allow for Model's scopes or contexts. The idea that there are Sub-models that can coexist. (You could call them "scoped singleton's", shared only within a context (scope).
- Allows for easy project growth. As the project grows, it is still easily maintained, and could be easily re-factored if necessary.
- Easy to learn, quickly to implement.
So we did a little research and came up with the following options:
- Make our own. Hah hah hah. We are a small team; we can't invest that much time, especially if there are several great options available.
- PureMVC. http://puremvc.org/
- Mate Flex Framework: http://mate.asfusion.com/
- Swiz Framework: http://swizframework.org/
- Robotlegs: http://www.robotlegs.org/
- Parsley: http://www.spicefactory.org/parsley/
Each has their positive side, and depending on your projects you might choose a different framework for different projects. Unfortunately for us, we can't invest time into getting to know deeply each one of them.
I did however take time to look at examples and read through the documentation of all of them, looked at what people like and dislike about each one of them to decide on what to use keeping in mind the list of what "better" meant for us, considering the projects that we currently have lined up.
So I'll explain the reasons why we chose to go with Parsley for some of our projects. I really want to stress that I don't think that any of these frameworks are "wrong", nor "bad". They implemented similar goals in different ways which have their unique benefits, but we evaluated their features according to our goals. Your goals will be different, so you should do your own evaluation.
- PureMVC. The idea is actually good. The goal is to have a framework that works in multiple environments. So if you code in multiple languages or use multiple platforms, it sounds good. But to accomplish that, it must make sacrifices and not exploit the Flex's sdk as it could. The other issue is that it uses a similar singleton approach as Cairngorm does. So it was out of the contest quickly.
- Mate Flex Framework. A lot of people like Mate, and I understand why. It nearly fills all of the requirements we were looking for. What I don't like about Mate is its glue mechanism. Decoupled objects eventually need to be coupled (or glued) together for your app to work. Mate uses "Map" files that describe how to glue (couple) things together. Map files are great in the sense that they illustrate the logic of how the app works. So a developer new to the app, can easily catch on how things are tied together, something a bit harder in other frameworks. So what's not to like? Well, Map files are built using MXML, and doing logic in MXML is just weird. I could get used to it, but what I really don't like is that Map files tie Objects/Models/Commands to properties or methods, but it does it through string variables. This means that you will not get compiler errors, and you have to be careful when you re-factor, as to make sure your Map files also get updated. You have to be even more careful if you use the same property name in two different components and decide to refactor one of them. Also, I fear that as the project grows and expands Map files could grow to be a pain to maintain, as they centralize the coupling of just about everything. I know you can distribute the Map files into several map files, but I still think it can become a pain. I do like the fact that it doesn't require custom metatags, and it works well with modules.
- Swiz Framework. Swiz follows a completely different approach on how to wire (glue, couple) your objects together. Swiz uses and Autowire feature, where objects are glued "Magically" by themselves. Ok it's not magic, it uses custom metagags, but it doesn't require a Map file. Actually, Parsley and Robot Legs both follow this same basic idea, where it comes to Dependency Injection. The framework figures out what to inject based on the properties Class type. You don't have to manually specify it, it just happens at runtime. You might ask: So what if I have two Models of the same Class type, although unusual, it's not a problem, it has a simple solution. Actually the way the messaging is done is similar to Parsley's messaging. So if Swiz and Parsley are so much alike, why Parsley? Simply put, Parsley has more options. Swiz frameworks messages must be Flex Events. Parsley's can be Flex Event's but don't have to be. Parsley is more friendly to Modules, and Parsley's lifecycle is automatically tied to the view lifecycle, which means that there is even less to worry about. If you wish to control the lifecycle manually in Parley, you still can. Parsley is simply more mature and more "flexible".
- Robotlegs. Robotlegs is the new kid on the block, and gaining lot's of momentum. Robotlegs isn't based on Spring like most of the other frameworks. Robotlegs also provides an implementation of (MVCS, Model View Controller + Service) Robotlegs does DI in a similar way that Parsley and Swiz do, but messages are handled a bit different. You use something similar to addEventViewer of Flex, but it's coupled to the framework and not the specific implementation. It has a similar concept of Context as Parsley does, but in Robotlegs you must extend a Context class from Robotlegs. Parsley let's you define the Context as Object in MXML or even in XML and load it at runtime. Robot Robotlegs includes Mediators, similar to the concept from PureMVC's mediators. One key aspect of mediators is that they allow you to isolate the view from the rest of the application. Basically they allow you to have little to no code in the view, and certainly no logic that ties it to the particular implementation. If that's your goal, then you can easily to the same with the "Presentation Model (PM)" which Parsley easily supports. Actually Flex 4 has this concept built in with the new Spark Skins, you can totally isolate the View from the logic. But in Parsley you can certainly use PMs without spark skins, or Flex 4. If you really have to have mediators in the PureMVC style, then you should strongly consider Robotlegs. Which is better? That's a matter of choice, we have started to use Robotlegs in our latest project for one specific reason: Although Parsley does allow you to add objects to the context at runtime after the context has been created, they are treated differently, in Robotlegs, all objects are added to the context after it's been created, and treated exactly the same, that is a very particular requirement from us in our latest project. This isn't an issue in the vast majority of projects. In brief, you can use Robotlegs in a similar fashion as Parsley, or you can follow it's pattern inspired by pureMVC. The key difference is that in Robot legs you configure and use the framework through ActionScript, while in Parsley it is done through Metatags, MXML and/or XML.
Parsley easily met all our original requirements. It is very flexible, it works in Flex and in pure AS3 projects (Flex not required, although in it's latest versions it is departing from Flash), it is simple, it makes sense, it does what you expect it to do, you don't have to extend the framework, but you can if you want. Parsley is easy and it doesn't require you to write any AS to tie things together nor to extend any of it's classes. You don't even have to follow an MVC pattern for it to be useful. Actually Parsley is not aimed specifically to implement an MVC pattern, it just helps you with it, and you can chose any patter that you like.
That doesn't mean it's perfect. Parsley uses custom metatags, which translate to issues with the compiler. When using RSL's or Modules, you must instruct the compiler to keep the custom metatags, or it simply won't work, and worse, sometimes it will fail silently. I guess that one thing that is debatable if it's good or bad is that in Parsley there is more than one way to accomplish the same thing, it's good because you choose what you like the most, or fits better, it's bad because it could lead to inconsistency, which could make working as a team a bit more difficult. Flexibility does have a price, but it's a matter of coordination, and I rather have the flexibility and use it responsibly than not have it at all.
Well, that's why we chose to use Parsley. I will write a series of articles with examples to help you get started with Parsley, or just learn about it. It will start with very simple examples, and move on to more complex scenarios to really show the power behind it.
Next -> Parsley's Basics