Building Framework Independent Code Libraries

I’ve recently encountered a couple of libraries that despite being 99% pure AS3 had minor dependencies on the Flex framework that prevented their use in ActionScript projects or in Flash without modification. This is unfortunate, because it limits the immediate usefulness of the libraries, and fragments the community’s access to them.

Regrettably, this approach is (unintentionally) promoted by Adobe. There is a ton of useful code distributed in the Flex SDK with minor or no dependencies on the framework, and no effort has been made to eliminate those dependencies and distribute / identify those classes for use in non-Flex projects. I’d love to see some kind of identifier / documentation for framework independent code, and have it distributed with Flash as well.

<tangent>Moreso, I’d love to see a core UI framework that is shared between Flash and Flex, and is extended (in the general sense, not necessarily via inheritance) with Flex specific functionality (and the bulk that implies). It’s time for a unified component framework in the Flash platform! But that’s a rant for another post.</tangent>

So, what strategies can you use to create framework independent libraries?

The most obvious approach is to avoid including framework dependencies whenever possible. For instance, use an Array or Vector instead of an ArrayCollection. It’s platform independent, and a lot more efficient. Almost all of the libraries I release use this approach. Of course, this isn’t always possible or desireable, so we need other solutions.

From an architecture standpoint, you can utilize inheritance, interfaces, and composition to append framework specific functionality to your core code.

Inheritance allows you to “branch” your core logic to create framework specific subclasses, including all framework imports. This comes with all the usual caveats of inheritance, including making sure you define methods appropriately to make it easy to override ones that will become framework specific. Generally you will have a functional core class to use in ActionScript projects, a Flex specific subclass, and potentially a Flash specific subclass.

Composition can provide a more flexible approach. You can build your core classes to rely on plugins that encapsulate all framework specific logic, and which define a simple interface. By default these plugins can point to a framework independent implementation (even to the classes that use them). As a simple example, you could have an ITextInputMediator plugin that exposes methods and events for working with text inputs. By default it would point to a TextFieldMediator class, but could also be pointed at a FlashTextInputMediator or FlexTextInputMediator classes.

The act of setting up these plugins could be done manually by the library user, or could use a keystone class. This class would be compiled into a project once, and would import and assign the appropriate plugins and factories when it initializes.

You can also use conditional compilation to toggle imports and logic blocks based on the environment. For the most part, this offers the cleanest approach, but you must ensure to document it clearly, as conditional compilation is not yet widely used or understood in the Flash world.

Locally, you can leverage reflection (ex. getDefinitionByName and the “in” keyword), dynamic access, and events to your benefit. The first two should be used as little as possible, because they come with unwanted side effects like reduced compile time error checking. Because the event model exists at the player level, you can listen to any event from any IEventDispatcher object, without having to reference its type directly. SPL uses this to listen for “valueCommit” events from Flex controls, without having to import the framework – it uses a local constant for the event name instead of importing the Flex event object.

As a last resort, if your library has dependencies on well encapsulated Flex framework classes (ex. utility classes like HashUtil), you could choose to distribute them with your library to make it easier for users to get running. Always test the package in isolation to ensure you have included all of the dependencies (like that pesky Version.as file), and document which classes you included, so people using your library with Flex can optionally delete the copies you included.

Making your libraries more widely usable means they can be used by more people, which is really the point to releasing them. It also helps provide a more consistent code base for all Flash platform developers, regardless of the framework they’re using. If you aren’t going to make your library framework independent, at least consider trying to architect it in such a way that another developer could more easily modify it to work without the dependencies.

Now let’s see what we can do about encouraging Adobe to embrace this idea internally. 🙂

If you have other approaches or ideas on creating platform independent libraries, feel free to share in the comments.

Grant Skinner

The "g" in gskinner. Also the "skinner".

@gskinner

12 Comments

  1. The simplest way I find is to not include any framework classes or swc’s in your classpath at all. Having them naturally missing from code hinting forces you to come up with independent solutions.

    Also, have you contacted the library owners? They might be unaware of the dependency.

  2. Some of the most widely used dependencies on Flex are its databinding, collections and MXML support. The opensource project Flight (and now Reflex) is using a custom databinding and collections solution that was built to work seamlessly in Flex and Flash alike. The binding is also 100% weak-reference, smaller and faster than the MX binding.

    Flight also links in the few Flex dependencies to support an MXML workflow in an ActionScript-only project, which means you can create custom components and definitions in MXML without the Flex Framework.

    We are at the point where it makes sense to separate these core solutions into a Core-Lib that anyone/everyone can build off of – it’s still a dependency, but it’s much smaller, can be used in Flex AND Flash, and can be managed by the community without the weight of Adobe’s development cycle. That isn’t to say we wouldn’t be thrilled to see Adobe adopt the library or take influence from the approach.

    We’re still trying to find a good home for the solutions, likely on the FlightXD website hosting Flight Framework.

  3. A lot of people are using private classes (i.e. defined in the .as file of another class). Last time I checked, this didn’t compile in CS4, which is a pain.

  4. I have an other question may be relative to this topic. It about dependency of flash player version instead of framework.

    I am working with some code which need to target AS3 player 9. I do know it will take advantage when target player 10. That the problem, how can i make the source code managed good to target both player.

    Now, i am working like this. Some core code are written to compatible with player 9/10 along with some basic interface class. And there will be different functional class which target different player will implement those interface.

    Any idea for better approach to dealing with this problem.

  5. Good points here! It’s usually the SpriteAsset or BitmapAsset class that ends up somwhere unintentionally for me. The whole concept between Flash and Flex is mixed up now. For example many of us use the Flex compiler to build Flash apps. It all raises the question why there is a special compiler for a ‘framework’ in the first place! IMHO Adobe needs to decouple the compiler from the Flash IDE and make it a universal compiler for both Flash and Flex and split classes from the Flex framework that are not bound to it.

  6. “The most obvious approach is to avoid including framework dependencies whenever possible. For instance, use an Array or Vector instead of an ArrayCollection.”

    ArrayCollection is platform independent along with all the binding stuff (we’ll you can use it in Flash apps)

    Adobe should also be implementing interfaces extensively instead of hard coding to classes. This would then open up all code to a custom implementation, removing Flash or Flex dependencies.

    Here’s a typical example, meaning FXG can’t be used with Flash.

    https://bugs.adobe.com/jira/browse/SDK-25601

  7. Hi Grant, all valid points here that I myself have encountered as a framework developer. I wish Adobe would provide a separate library with a subset of the Flex framework (like Logging, …) that could be leveraged in pure AS3 projects.

    I do want to point out that there is a community effort with the AS3Commons project. There is already some good stuff in there, and I’m sure there is a lot of room for improvement. http://code.google.com/p/as3-commons/

    cheers,

    Christophe

  8. I think at one point there was a drive to take Flex in a completely separate direction from Flash, but over time it was realized that supporting existing Flash devs was as important and winning Java/C# devs. The code reflects those business goals. I agree with Sascha’s comments above regarding one compiler to rule them all.

    -t.

  9. Amen to that! I don’t use the Flex framework because I don’t need it. However, in every project I work on, I would love to be able to simply “borrow” some classes from the Flex framework, most notably the classes in the mx.rpc package. I hope someone from Adobe is reading this…

  10. The AS3 Corelib is guilty of this. I recently tried to use some of the date utilities and ended up having to hack a couple of classes which just dealt with constants – think it was DateBase – grr.

  11. “most notably the classes in the mx.rpc package”

    Again I’m pretty sure this isn’t dependent on the Flex framework. What specifically are you trying to use from there that you have a problem with?

  12. Hi Tink! I’d love to use the WebService class from the mx.rpc.soap package. However, as soon as I use it, my .swf file gets about 184kb fatter! So I’m guessing that I’m actually compiling the whole Flex framework instead of just the classes that make up the Web Service.

Comments are closed.