Gumbo Component Architecture 4 Dummies

Flash releases tend to operate on the each-kid-gets-a-turn principle: one for the developers, one for the designers. After reading this article on Gumbo component article, however, I think Christmas might be come early at Adobe. Because if designers will luv Gumbo's new skinning model, developers will luv luv luv the new component architecture.

Adobe has laid down three principles for the redesign:

1. Design Friendly: clean separation of visuals and logic
2. Composition: easy to group and relate building blocks of functionality
3. Extensibility: easy to extend

Alert developers will notice a definite redundancy to this list. Composition is the indispensable bullet point. Composition requires that functionality has been encapsulated. And if it is encapsulated, it is cleanly separated, so Design Friendly is just a direct corollary of Composition. Likewise, if it is encapsulated, it has Extensibility simply because well-encapsulated functionality is easier to locate and subclass or compose.

Alert developers might also ask why encapsulation is coming to Flex components only now, in the fourth iteration of Flex? It's not as if MVC is a fresh styling. But hey, every Flex contributor is smarter than me, and the whole team has been operating under constraints I don't understand--or particularly care about--so let bygones be bygones.

What Stays the Same

Since Flex is just components, changing the component architecture is huge. That said, the moving parts look and work exactly the same. The managers for focus, pop ups and dragging, the preloader frame, the build process that bubbles up from the least to the greatest components, the event cycle--all are the same.

The handles by which the framework updates components by the batch (commitProperties, measure, updateDisplay) are also the same. What changes is how the component classes implement these updates. Before Gumbo, they took on the entire responsibility. With Gumbo, they hand off this responsibility to various internal objects.

One Complete Skin

Before Gumbo, skinning was handled piecemeal, mostly in CSS:

Actionscript:
  1. Button
  2. {
  3.      upSkin: Embed("assets/buttonUp.png");
  4. }

The fact that a component could take a partial skin and relate it to another partial skin dramatizes the problem Gumbo will attempt to solve: because the logic of the view is jumbled up with the component's other logic, it becomes a chore to manipulate.

In Gumbo, the view emerges as a single object in own right, a tweakable, swappable instance composed by the component:

Actionscript:
  1. <List skinClass="myCustomSkinClass"/>

MXML Skins

So what does this skinClass look like? It looks like MXML, of course. Declarative graphics a la Degrafa have been integrated into Flex:

Actionscript:
  1. <Rect id="rect">
  2.         <fill>
  3.             <LinearGradient rotation="90">
  4.                 <GradientEntry color="red" />
  5.                 <GradientEntry color="white" />
  6.             </LinearGradient>
  7.         </fill>
  8. </Rect>

These graphics can be coded by hand in a skin class, but the typical work flow will entail exporting graphics data from a tool in Creative Suite (Flash, Illustrator or Fireworks all export data in the FXG format that Flex uses) and opening the data in Catalyst, where it can be associated with a particular component and prepped for Flex Builder. This flow should ease the painful back-and-forth between developers and designers that plagues Flex development.

Controlling the View with State

So the view has been encapsulated...how then to control it? With Gumbo, there is just one way: by setting the currentState property of the skin instance. So finding where a component is controlling its skin is as quick as searching for "currentState=". Actually, it's even quicker, since skinnable components implement a getUpdatedSkinState method that centralizes the logic for setting the skin's state.

Along with new responsibilities, states accrue new powers. Now states can be declared empty and defined variously with inline MXML:

Actionscript:
  1. <fill>
  2.      <SolidColor color.invalid="red" color.valid="green" color.up="gray"/>
  3. </fill> 
  4.  
  5. <fill.invalid>
  6.        <LinearGradient>
  7.               <GradientEntry color="red" />
  8.               <GradientEntry color="orange" />
  9.          </LinearGradient>
  10. </fill.invalid>
  11.  
  12. <fill.valid>
  13.        <LinearGradient>
  14.              <GradientEntry color="green" />
  15.              <GradientEntry color="white" />
  16.        </LinearGradient>
  17. </fill.valid>

This syntax should save time and make MXML more readable when states offer numerous small variations.

Layout

Gumbo components delegate layout to a Layout object. A List subclass, for instance, becomes vertical when it composes a VerticalLayout:

Actionscript:
  1. <layout>
  2.     <VerticalLayout/>
  3. </layout>

A horizontal List would likewise compose a HorizontalLayout:

Actionscript:
  1. <layout>
  2.     <HorizontalLayout/>
  3. </layout>

A tile List would, naturally, compose a TileLayout:

Actionscript:
  1. <layout>
  2.        <TileLayout columnCount="3"
  3.           rowCount="3"
  4.           orientation="vertical" />
  5.  </layout>

In Gumbo, there is no separate HorizontalList, VerticalList, and TileList per se, only a list that can be directed to contort itself a number of ways. Simple, no? If you want a slightly different layout, you know where to look and what to subclass.

Better yet, I'd commence googling, because the Flex community is bound to generate every Layout class under the sun: CarouselLayout, RandomLayout, etc.

Power of Composition

What's enticing about Gumbo is that your power multiples with each new compositing. Suppose you have 3 FlowerList subclasses. And 3 List-ready skins, each with a unique item renderer. And 3 Layout classes. That's 3 variations of FlowerList, times 3 possible layouts, times 3 possible skins, for 3*3*3=27 variations.

Permutability is the well-known virtue of composition, and the overriding goal of "Gumbo," aptly named after the thrown-together soup. So it's worth remembering what a maddening pain point it now is.

Currently, if I have some flower-specific code in a subclass of VerticalList, then later find that a TileList for flowers is necessary, there's a problem. Flower-functionality has been tied to a particular view, the VerticalList. So how do I put that functionality in another view? Either I extract the functionality into a FlowerData class, then compose and wrap it in two separate subclasses of VerticalList and TileList...or I do the unmentionable...I won't say what, but in the middle of the night, with some very marginal, dead-end classes, I've done things...things I never, ever did as a Flash developer.

The pure among you might say that I should have started with composition and FlowerData in mind, instead of immediately, sloppily subclassing some MXML component. Yes, my friend, you are right. But keep in mind that composition is not costless. Encapsulated functionality needs to be regathered and coordinated. If it is exposed, many tedious wrapper functions need to written. Is this always the best course?

If Gumbo fulfills its promise, this painful question will often become irrelevant, because Gumbo will make it trivial for Flex coders to practice composition. This is, after all, the great advantage of working with a framework, that it does the work of relating groups of classes for us. So while the framework does the hard work of mediating and wrapping and implementing the components' new internal organs, we will just accessorize. That smells damn good to me...I'll take a large bowl of steaming Gumbo.

Deeper with Flex

After reading the architecture article, I'm excited about Flex in a way I haven't been since the honeymoon period, when there seemed to be a clever event planned for every contingency, and the productivity wallop of just a few lines kept surprising me.

Do you remember that? Then you will also remember how quickly the honeymoon dissipated, when trivial adjustments suddenly morphed into afternoon-sucking spelunkathons.

What if I wanted to add an extra space after every third item in a list component? Hmmm, maybe subclassing updateDisplayList or some renderer wouldn't cut it...and soon enough, I'm scanning this huge, multi-indented function in which data, layout and interaction are tangled like so many hairs in a hairball. Hmmmm...maybe that extra space is a "nice-to-have."

In principle, I was willing to dive deeper. An industrial-strength framework like Flex requires effort to master, no doubt. But the code I explored didn't inspire me to plunge unless absolutely necessary, because the payoff typically amounted to one-off tricks and workarounds.

I hope Gumbo changes that.

I live in Portland, Oregon, and I'm looking for work. More about me.

3 comments.

  1. [...] and propelled by their own logic. This is a many-splendored turn for the better, which I explore here from a programmer’s [...]

  2. This topic looks great. For more Flex 4 and Flash Builder 4 information, see this new course 'Flex 4 Top 10 Features' taught by Rivello Multimedia Consulting. Sign up or request it come to your town today! http://www.blog.rivello.org/?p=324

  3. Very useful information. Thanks for posting

Post a comment.