Viewing by month: February 2007

Feb 25 2007

Release a framework? Are you sure you *want* to?

There's a new twist on the eternal frameworks debate going on: now we're not just talking about whether or not frameworks are good, but if you should release one that you've written. In this post, I'm not going to state my opinion (Sean's said it better than I can, in just the title alone). Instead, I'm going to talk a bit about things I think you should consider before releasing code, mostly taken from lessons I've learned.

Be Ready for the Flames

If you release code, you're attaching your name to it. Even if it's a "take this, play with it, do whatever you want, I'm not finishing it" release, you're associated with it. No matter what you say, you will receive e-mail about it not working. People will ask for fixes. People will bad mouth you. It is inevitable.

Existing Products Exist for a Reason

Examine the market. If there's a perfectly good wheel out there, and yours is only 1% rounder, expect a "WTF?" response. If this is what you're looking at releasing, round out that existing wheel instead of rolling your own (pun intended). If you're going to release, do a litmus test of whether or not the differences in your implementation matter to anyone. Find out if anyone else things an alternate needs to exist. Sorry if it sounds harsh, but it may not.

You're Only 25% Complete

Somewhere, somehow, someone's going to do something completely unexpected (but, at the same time, completely reasonable) with your code. People doing this kind of thing will make up a small minority of your users. They're not trying to screw up your life, just solve those little edge cases that make a system unique. Everyone system has them, otherwise we'd just be assembly line workers in software factories.

Unless you're omniscient, you're signing up for a life of solving other people's edge cases, spending 75% of your framework development time solving other people's problems. Sucks, doesn't it? Open source is supposed to solve this, right? Dream on, Stallman. Most of the time, either you're going to solve the edge cases yourself, or the squeaky wheels will result in a cloud of bad press for you.

Be Ready to Kill It

So I'm the Model-Glue guy, right? I'm also the ChiliBeans, Arf!, Paste, and Rocket guy. Be ready to say "enough is enough" and kill your project. Sometimes, a project's done its job if it's done nothing but kickstart others into starting/furthering their own. No, I'm not saying anyone should kill Mach-II.

4 comments - Posted by Joe Rinehart at 5:10 PM - Categories: Model-Glue

Feb 19 2007

Model-Glue is hiring! Seriously!

I'm proud of Model-Glue. Two years ago, it was a learning project for implementing MVC and II in ColdFusion. Now, it's both enabling ColdFusion developers and gaining in popularity on both Fusebox and Mach-II. After some serious thought on my bike today, I've decided it's time to open up the Model-Glue project and invite others to help out even take part ownership of the project.

Read more...

25 comments - Posted by Joe Rinehart at 5:13 PM - Categories: Model-Glue

Feb 19 2007

Flex + Cycling: My dream application!

I wish I had been a part of this - it's possibly the coolest Web app I've ever seen. Anyone who knows me finds out pretty quickly that I spend a good amount of time riding bicycles. Right now, the big deal in the US is the Tour of California.

Usually, "realtime" cycling websites refresh GIFs and text-divs. Tour de California went one extra: they mashed Flex, FDS, Yahoo! maps, GPS, and probably a few other things in one amazing race tracker. Even if you don't care at all about cycling, you've got to check this out.

2 comments - Posted by Joe Rinehart at 2:45 PM - Categories: Flex

Feb 9 2007

Adding a "ViewController" into your Cairngorm app

The other day, I posted about adding Cairngorm event listeners directly into your views. Just summarizing it like that, it should already sound like a wonky alternative to using ViewHelper/ViewLocator (which, to me, is even wonkier).

Here's my situation:

I have a login form that I'd like to have to something "special" when login fails, like blink or turn red or play a very loud siren noise. Whatever that is, I can't get there by just binding to a "workflow" value in the ModelLocator: I need to call a function in the view.

Jay Proulx posted a possible solution that created a separate "ViewController" concept, where a class would extend Canvas and define string constants representing various states. It's a nice way to separate the listeners out of the views, but it still doesn't go where I need to be: having functions that play things like effect sequences in response to architectural events.

So, I combined his idea, mine, and the basic UI event system to create my own ViewController class.

Here it is (nothing special):

package com.foo.control

{
   import mx.core.UIComponent
   import com.adobe.cairngorm.control.CairngormEventDispatcher;

   public class ViewController extends UIComponent
   {
    private var dispatcher:CairngormEventDispatcher = CairngormEventDispatcher.getInstance();
   
    protected function addListener(eventName:String, func:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void {
       dispatcher.addEventListener(eventName, func, useCapture, priority, useWeakReference);
    }
   }
}

Nothing fancy. Extends UIComponent and adds an addListener() method that'll add a listener to the CairngormEventDispatcher.

However, I can then extend it with something like LoginViewController. LoginViewController adds a listener for the USER_LOGIN_RESULT_EVENT, and depending on the authentication status of the user involved, raises a plain old UI event:

package com.foo.view.controllers
{
   import com.foo.control.ViewController;
   import com.foo.control.user.AuthenticationController;
   import com.foo.control.user.UserLoginResultEvent;
   import com.foo.model.user.User;
   import flash.events.Event;

   [Event(name="loginFailed",type="flash.events.Event")]
   [Event(name="loginSuccessful",type="flash.events.Event")]
   
   public class LoginViewController extends ViewController
   {
      public function LoginViewController() {
         addListener(AuthenticationController.USER_LOGIN_RESULT_EVENT, loginResult);
      }
      
      private function loginResult(result:UserLoginResultEvent):void {
         var u:User = result.user;
         var e:Event;
         
         e = u.authenticated ? new Event("loginSuccessful") : new Event("loginFailed");
         dispatchEvent(e);
      }
   }
}

Now I'm in business. Instead of dealing with views by an arbitrary ID (my main issue with ViewLocator/ViewHelper) or giving my view knowledge of the Controller view (my main issue with my earlier workaround), any view that wants to deal with login failures or login succeses can do this:

<viewControllers:LoginViewController loginSuccess="doSomething()" loginFailure="playAnnoyingSirenSound()" />

It's a bit like ViewHelper, but backwards enough where it works implicitly instead of explicitly.

10 comments - Posted by Joe Rinehart at 8:04 AM - Categories: Flex | Cairngorm

Feb 8 2007

Flex Security: SessionFacades, AOP, and CFLogin

A while ago, Ray blogged a series on using securing Flex using remote credentials and CFLogin.

I don't think I've ever actually used CFLogin in a production application, but I'm going to: when combined with a session facade and ColdSpring, it starts to turn into a really slick (but somewhat complicated) way to secure Flex applications. Chris Scott got me started thinking about this at the Frameworks Conference last week, and I've just implemented it inside an app I'm working on, and I can already see it saving me massive time down the road.

Read more...

4 comments - Posted by Joe Rinehart at 9:24 AM - Categories: Flex and ColdFusion

Feb 7 2007

Stupid Cairngorm Trick: "View Listeners"

I like Cairngorm. I know some folks see it and say "whoa...that's a lot of classes for a single gesture. Events, Commands, Controllers, Delegates, Locators...aieee." However, "everything in its place" mentality and separation of concerns it enforces really appeal to me.

However, one thing I absolutely can't stand is the ViewLocator/ViewHelper bit. The design forces causing it (separation of controller from knowledge of currently existing views and their implementation) are natural, and require a solution. I'm just not sure ViewHelper/ViewLocator are the right answers. They leave me writing code that still knows about the ID strings with which ViewHelpers have registered themselves.

Let's wrap a use case around this: I have a UserLoginEvent mapped to UserLoginCommand. When the UserLoginCommand gets its response from the backend server, I've got some view behavior that I'd like to take place that goes beyond what binding to the ModelLocator can provide. In other words, I need to call a function named loginFailed() on the view. Using ViewHelper/ViewLocator, I can add a ViewHelper to the view that exposes a loginFailed() function that the command will call: its purpose is to call the actual loginFailed() function on the view, disconnected the view's implementation from the command/controller layer. Complicated.

I started looking through the core Cairngorm code last night, and I noticed that the CairngormEventDispatcher's addEventListener() message just wants two parameters: the name of the event listened for and a reference to a listener function.

In Model-Glue terms:

<message-listener name="someMessage" function="someFunction" />

In Cairngorm, as in Model-Glue, the function referenced is normally on a controller.

However, unlike Model-Glue (and HTML apps in general), Flex/Flash gives us the ability to have views respond and change their display without reloading the page. This means there's no technical reason why the listener function couldn't be on a view.

By adding functions acting as intialized() and removed() handlers, you can add code to your view that listens for events, just like the controller:

private function addViewListeners():void {
   CairngormEventDispatcher.getInstance().addEventListener(AuthenticationController.USER_LOGIN_RESULT, loginResults);
}

private function removeViewListeners():void {
   CairngormEventDispatcher.getInstance().removeEventListener(AuthenticationController.USER_LOGIN_RESULT, loginResults);
}

Now, through a sequence of events, I can have the UserLoginEvent's handling code fire a UserLoginResult event. When it's dispatched, my view will "hear" it and fire its loginResults function. Simple.

Conclusion

The CairngormEventDispatcher allows for functions that aren't just methods on the controller to be added as event listeners. By taking advantage of this, we can allow views to respond to architectural events as well as controllers.

It's not without problems: our view is suddenly bound to Cairngorm's event architecture. I'm also not sure how much this stretches MVC...the model's still completely separate, which is my largest concern. It's just that the views are taking on some knowledge of the controller tier (names of events, existence of certain controllers used to get those names, the dispatcher itself) that I'm not sure they should have.

Thoughts?

10 comments - Posted by Joe Rinehart at 7:38 AM - Categories: Flex | Cairngorm

Feb 5 2007

I love the VAR scope!

I have a confession. I happen to be a fan of the var scope. I know, it makes me an odd duck. However, to my (warped) mind, it makes sense. If Adobe makes it an "option" in Scorpio or whatever ColdFusion 9 is called (Neo...Scorpio...Blackstone...how about something simple, like "Frank"?), I'm going to be one unhappy camper. There are already enough ColdFusion folks out there right now who don't yet know "this" vs. "variables" vs. "arguments" - let's not add "well, depending on your configuration, variables sometimes, var other times..."

So, why do I like VAR?

Reason One: Cohesion Warnings

I think it's because I come from a pretty cohesive school of thought - I don't think of CFCs as being anything like function libraries. Their natural interaction of the functions should be to share data, not isolate it.

To me, the more local variables I have, the more poorly designed that function becomes. That's not to say I don't wind up with five to ten local variables on a regular basis, but when I start to see that many declarations, I begin to notice that the method is taking on too many roles, and it's time for a bit of refactåoring. It's like having too many moving parts in once place.

Reason Two: Forces "Instance" Mentality

It's a bit like reason one, but I think having to think about "local" versus "instance" keeps people more in tuned with thing in terms of "objects" rather than "procedures." If, by default, you're thinking about the method's scope first and object's scope second, I think you're leaning towards functions as procedures rather than behaviors of the object.

Reason Three: ActionScript 3.0 and var is somewhat similar

In ActionScript 3.0, if you want a method to be local to a variable, you var it. For example, binding to the "bar" member of the following class could have some nasty, accidental results:

public class Foo
{
[Bindable]

public var bar:String = "I am the instance version of bar."
   
public function Foo() {
   bar = "I am the value set in the constructor.";
}
   
}

Yep, just like CF, the "bar" assignment in the constructor would overwrite the class member bar (variables.bar!).

If that line is changed to this...

var bar = "I am the value set in the constructor.";

...you're back in business.

Conclusion

So, yeah, I like the var scope. It means I don't switch thought patterns between ColdFusion and Flex, and it forces me to think about the object, not the procedure. Yes, it's bitten me in the rear a few times (causing threading issues in Model-Glue causes a serious bad day out when people get latest from Subversion!) - but, in the end, it results it better designed code. And that saves me much more time than typing "v-a-r" now and then.

17 comments - Posted by Joe Rinehart at 6:39 PM - Categories: ColdFusion MX