Thursday, September 20, 2007

Adobe Flex First Thoughts: Part I

I was able to sneak into a two day Adobe Flex 3 training session a few weeks ago, and now I've finally had a chance to write down what my impressions are of the language and environment. This is Part 1 in a 3 part series on Flex. Today covers the Flex language, next up is the Flex Builder Eclipse Development Plugin, and last is the Flex Server and Adobe Integrated Runtime (AIR) components.

As a word of warning... these are opinions generated by a mere 16 hours in training. Errors and omissions should be expected (that's what the comments are for).

Flex is Adobe's platform for web applications. To the end user, the application produced looks like any other Flash application running in the browser. But the difference between the Flash and Flex development environments is large.

Unlike the Flash development environment (now called CS3), Flex has no concept of a movie, a stage, or a time line. This is good news for programmers because development no longer feels like it is taking place in an animators studio. Instead, Flex ships as an Eclipse based plugin. The IDE looks great: there is a nice looking UI builder, the Eclipse project wizards seem to work, the IntelliSense works good enough, and the debugger contains all the expected Eclipse options. The compiler is available for free, it is only the Eclipse plugin and the Flex server that requires a purchase

The Basics

Flex applications are written in mxml, which is really just an xml file. The file contains xml based component definitions ("put text box here"), css to determine look and feel ("background is green", and ActionScript 3.0 to handle behavior ("MyTextBox.onClick(Event e)...").

For me mxml was a bit of a turn off because it mixed the xml, ActionScript, and css all in one file. Even with the syntax highlighting, there was a lot of noise to sort through when you wanted to get down to the business of editing ActionScript. It looked like all the naive sample Java Swing applications that Sun published (you know, where every sample is one big class that extends from JFrame). These examples influenced thousands of Java programmers, like myself, into thinking that every Swing app started with subclassing JFrame. Ack! Model, View, Controller anyone? I know this approach of mixing all three layers in one mxml file isn't required, and that css can be externalized to an application level css file. But it's sad to see Adobe implicitly promoting this style the same way Sun did with the Swing examples.

The good part of mxml is that it could drive component driver development. Each mxml file is typically a visual component that extends an existing widget and adds functionality to it. There are currently hundreds of existing components in the base component library, and more are available on the web for free and otherwise. All of the dependencies are located within the component, and the application is simply a shell that assembles these components into a coherent layout. Nice and reusable. Just like COM! Wait... that doesn't sound good. But it is like COM in that the goal is to define reusable components that developers can add to their component library. And it seems like Adobe wants to make it easier for 3rd parties to create and resell components, just like the COM business model. A ramification of this model is that 3rd parties become very important to the success of both Flex and COM. All the components look great today: crisp, well-animated, modern looking. But in 5 years they are going to look old, dated, and clunky. Everyone knows a VB 5 application when they see one; in 5 years will Flex apps be the same? The answer is maybe, depending on what happens with the community and what Adobe contributes.

Working with Widgets

Within the mxml file, Flex visual components are defined and laid out using xml markup. Verbose? Yes. Old Fashioned? Yes. Industry Standard? You betcha. The nice part is that layout and positioning are controlled within the component declaration. Compared with Swing's GridBagLayout, the Flex layout mechanisms were a joy. It was a lot of containers and alignment attributes, but it was all intuitive, especially for someone versed in JPanels and scarred by GridBags. What's more, there was an absolute layout option. Why did Java never include this with Swing? VB has always been easier to prototype with than Java, and my opinion is that the missing absolute layout manager has a lot to do with it. VB UI's were a breeze to throw together, and so are Flex's. The downside here is that resizing doesn't work. For a rich, pretty website designed by a graphic design professional, this might be a non-issue. But most pages I piece together benefit from resizing. As monitors grow in size, a blog column constrained to 600 pixels doesn't make sense.

But wait? Wasn't css part of the mxml? If you lay out the page in XML, then what does the css do? The answer: css only controls looks such as color and fonts, not the size and layout of the components. I love this because I've never graduated beyond html tables. Never once have I gotten css positioning to work. And now I don't have to!

Hopefully, most my time with Flex will be spent with ActionScript 3.0, making the components behave the way I want. I've been told at times that AS 3 is a subset of Javascript 2, a superset of Javascript 2, and that both are based on ECMAScript. It seems to me like both are based on ECMA, AS based on edition 4 and JS based on edition 3. Anyway, you get all the nice features you'd expect like anonymous functions, object prototypes, and the mixins that go along with it. For anyone with a passing knowledge of Javascript, the ActionScript language shouldn't be hard to learn. One cool feature is that the Flex compiler has a command line switch on whether to enforce static/strong typing or to allow dynamic/weak typing. The demonstration I saw was strongly typed, but a little exploring exposed this option. Exciting! In Java, I've been advocating having production code written in Java (static/strong typing), but unit test code written in Groovy (dynamic/weak typing). This allows me to refactor the production code without worrying about compiler errors, which simply serve to slow down many refactorings. I lose the ability to think out loud with code, and find myself thinking for short periods of time and then fixing all the compiler errors I introduced. (Technically, what I want is static typing in production code and dynamic, but strong, typing in unit test code, but getting dynamic is an improvement). (More technically, what I really want is weak, dynamic typing for both lines of code and the good tool support typically associated with static types)! Anyway, it looks like static typing in production and dynamic typing in test is supportable with Flex. It would just take some clever code organization and build scripts. Awesome!

Working with Data

One of the best parts of a dynamic language is the parsing and text processing capabilities. XML creating and parsing is a breeze with Flex. Look how easy it is to create a large XML document:


var employees:XML =
<employees>
<employee ssn="123-123-1234">
<name first="John" last="Doe"/>
<address>
<city>San Francisco</city>
</address>
</employee>
<employee ssn="789-789-7890">
<name first="Mary" last="Roe"/>
<address>
<city>Newton</city>
</address>
</employee>
</employees>;



This is more intuitive to me than the equivalent Groovy Builder object that uses closures to build XML. Accessing XML is a snap too. Just take the XML object and reference it without the endless findChild(), findAttribute() method calls associated with Java parsing:


employees.employee[0].address.zip; // 98765
employees.employee[1].@ssn; // 789-789-7890



This whole thing makes me happy.

Flex components are tied to data sources, such as web services or files, using a very similar technique to Visual Basic's component bindings. A component itself has a data source attribute which references an ActionScript variable declared as Bindable. This is simple, slick, and makes for a great demo. However, a DAO layer would definitely be needed for large-scale projects. Remember, not only does the mxml file have AS, XML, and CSS in it, it now also contains bindings to the data model. Separation of concerns was not a design principle for the training material. Sure, it could all be separated out, but Adobe does not seem to be leading the way for higher quality Flex designs. One nice thing about this data binding is how simple the Ajax integration becomes. Since everything you need is within the mxml component, the component itself can connect and update itself asynchronously without crossing any layer boundaries. I was similarly impressed with Grails custom tags and the ease with which they could be Ajax-ified. The two aren't that dissimilar to someone without in depth knowledge (me).

The Bad Stuff

One large downside of Flex is the lack of community and support. Try to do anything in Javascript and you can find hundreds of forum posts and articles describing how to do it. Try to do anything in ActionScript and it will be much harder to find examples. Moreover, some of the examples will be AS 2 or earlier. The few edge cases I found myself working with stumped me for quite a while, and lack of online help played a role. Also, there simply aren't as many people with Flex skills, so hiring good people might prove to be tougher (whereas, hiring awful Javascript programmers is pretty easy nowadays!). Flex does have good documentation from Adobe, which is modeled after Javadoc. Overall though I'm hesitant to invest a lot of time into something that may never be mainstream. But last month's Minnesota Flex User's Group had 30 people show up, so maybe this is the next big thing.

The other downside of Flex is the US$400 license you need to buy for the Eclipse development environment. While this isn't needed to develop Flex apps, it sure was nice. It's also the topic of the next part in this series.

4 comments:

Unknown said...

Hi Hamlet,

Hope you don't mind that this comment is going to be rather LOOOOONG.

Nice post! I agreed with most of it. Since I attended the 2-day training with you, I can see why you might be unclear on a few points (i'll list those below). Part of the problem with the 2-day training is that it was all based off of a single example that was gradually enhanced with each new lesson. So we didn't really get an opportunity to explore the various ways you can build applications in Flex. If you have a chance to experiment a little more with Flex, there are some really good lessons included in the help section of Flex Builder 2 (or 3 beta). Also the ActionScript cookbook that Ryan has is pretty good and is completely ActionScript based (no mxml).

The first point is just a quick clarification on pricing. Unless there is some sort of discount I'm unaware of, Adobe lists the cost of Flex as $499 and add another $250 to $300 if you want it bundled with Charting. The server side (Data Services 2) is actually free for the first license, which can be a steal for small businesses. The other nice thing is since Flex is client side technology, you don't even really need to purchase this server side at all for larger businesses since you can simply pass XML using SOAP or Restlets to access the database. That's one of the reasons that Ryan asked Justin to cover the E4X stuff during the 2-day training. This obviously won't be as fast as using DS2 but for small amounts of data it should be sufficient.

I agree with you about embedding code in MXML being bad and was a little disappointed in the training example for not using a better approach to this. This definitely is not the only way to code in Flex and I hope that the coding standards document that Ben is working on will address this. Just like ASP and JSP can either embed code or reference code, the same is true with MXML. Also, just like JSP is compiled into java classes, MXML is compiled into ActionScript classes. In fact, you are not even required to use MXML at all. Even better, you can do everything in an ActionScript project (no MXML) that you can in a Flex project (with MXML). The only downside is you won't be able to use the neat UI Editor that you mentioned.

Auto-resizing actually works great in Flex, but obviously you won't be able to do this in "absolute" mode. In HTML, you can set tables, images, etc. to be either fixed pixel width (same as absolute) or percentage width (same as auto-resizing). In Flex, it's the same idea but you have even more flexibility to auto-resize some things you can't in HTML, such as fonts. Since the examples in the 2-day training were all "absolute" based, the auto-resize was not covered very well. He talked about it BRIEFLY when he was describing the "anchor checkboxes" and drawing diagrams with the marker. It would have been a lot better if he could have demonstrated this in a lab exercise.

Before I start to sound like I'm trying to "sell you" on Flex, there was one point you made in favor of Flex that I actually see as a downside. This might be more of a programmer preference than a misunderstanding, but I really think the change from a loosely typed language (ActionScript 2) to a more strongly typed language (ActionScript 3) was a step in the right direction for Adobe, but I don't think they went quite far enough. Consider the following line of ActionScript code:

var myArray:Array = new Number[];

This line will compile just fine but generate the following cryptic runtime error EVERY time the array is referenced.

TypeError: Error #1007: Instantiation attempted on a non-constructor.

I know compile errors can be a pain, but what if you had this line of code buried deep in a section that is rarely ever called? Wouldn't you rather know about problems like this earlier on before your product is shipped and discovered by the users? Even in java, ClassCast Exceptions are fairly common errors users get when a programmer wasn't being careful enough.

Also consider the runtime performance of a loosely typed language versus a strongly typed language. Since all arrays are loosely typed in ActionScript, here is a really simple example that shows Java arrays are 60 times faster than ActionScript arrays. JavaScript (also loosely typed) is even worse.


Java:

public class ArrayTest {
public static void main(String[] args) {
int[] arr = new int[10000000];

//write test time is 31 milliseconds
long start1 = System.currentTimeMillis();
for (int i=0; i<10000000; i++) {
arr[i] = 1;
}
long finish1 = System.currentTimeMillis();
System.out.println("write test time: "+(finish1-start1));

//read test time is 16 milliseconds
long start2 = System.currentTimeMillis();
for (int j=0; j<10000000; j++) {
int temp = arr[j];
}
long finish2 = System.currentTimeMillis();

System.out.println("read test time: "+(finish2-start2));
}
}



ActionScript:

package {
import flash.display.Sprite;

public class ArrayTest extends Sprite {
public function ArrayTest() {
var arr:Array = new Array(10000000);

//write test time is 1702 milliseconds
var start1:Date = new Date();
for (var i:int=0; i<10000000; i++) {
arr[i] = 1;
}
var finish1:Date = new Date();
trace("write test time: "+(finish1.time-start1.time));

//read test time is 1155 milliseconds
var start2:Date = new Date();
for (var j:int=0; j<10000000; j++) {
var temp:int = arr[j];
}

var finish2:Date = new Date();
trace("read test time: "+(finish2.time-start2.time));
}
}
}

Hamlet D'Arcy said...

Great information Tom, thanks!

Ben also pointed me to a product called Cairngorm that he uses for a Flex DAO layer, as well as other services: http://labs.adobe.com/wiki/index.php/Cairngorm

This framework might alleviate my DAO layer concerns as well.

As for the typing... I understand the pain, and have found myself cursing at many PHP runtime errors in my time. I'm not sure I completely buy the argument that type safety can be achieved through the rigorous adherence to unit testing. This is because I'm not sure that it is always appropriate to write unit tests for everything. The principle of "unit test everything but could possibly break" has a different answer in a dynamic language than a static language. Something as simple as:

var myArray:Array = new Number[];

could break! Egads!

Thank you tons for my first comment ever.

Unknown said...

Hi,

I think the community around Flex and AS3 is probably quite a bit larger than you may realize.

Suggest you check out the community at FlexCoders: http://tech.groups.yahoo.com/group/flexcoders/ (900 messages in last 7 days).

There is also a good blog aggregator with 100+ Flex related blogs here: http://snipurl.com/1r3mo

There are also many articles here:
http://www.adobe.com/devnet/flex/

HTH,
David
David

Hamlet D'Arcy said...

I'm not saying the flex support and community is bad in absolute terms... only as a relative quantity comparison to JavaScript. There are more books, resumes, conferences, and forums that reference Javascript than ActionScript. http://www.googlebattle.com/index.php?domain=actionscript&domain2=javascript&submit=Go%21

A comparison of quality would be a lot harder!