<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>Agile software development using Kanban &amp; Scrum. We code Flex &amp; Ruby on Rails in Auckland, New Zealand.</description><title>vWork Development</title><generator>Tumblr (3.0; @vworkdev)</generator><link>http://devblog.vworkapp.com/</link><item><title>A pattern for handling validations in an associated model ...or how I discovered ActiveRecord::Rollback</title><description>&lt;p&gt;Recently I struggled a bit to find an elegant and working solution to validate an associated model when destroying another model’s instance. The two models were &lt;code&gt;Account&lt;/code&gt; and &lt;code&gt;User&lt;/code&gt; and I needed to validate the &lt;code&gt;Account&lt;/code&gt; whenever I delete a &lt;code&gt;User&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The two models look like this - very much simplified:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Account &lt; ActiveRecord::Base
  has_many :users, :dependent =&gt; :destroy
end

class User &lt; ActiveRecord::Base
  belongs_to :account
  has_many :roles # these contain authorization roles, such as ‘admin’
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The given rule to validate was:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;An account must have at least one user that is an admin&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This rule makes sure an account always has one administrator that can access all parts of the application.&lt;br/&gt;
When someone deletes a user within the app, and this user happens to be the only administrator, validation should prevent this from happening.&lt;/p&gt;

&lt;p&gt;I could have implemented this in the &lt;code&gt;User&lt;/code&gt; model, for example like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class User &lt; ActiveRecord::Base
  belongs_to :account
  has_many :roles # these contain authorization roles, such as ‘admin’

  before_destroy :make_sure_account_would_still_have_admins

  private

  def make_sure_account_would_still_have_admins
    self.account.users.admins.count &gt; 1
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But I didn’t want to do this. Firstly I wanted to use ActiveRecord’s validations and secondly I wanted to put this logic into the &lt;code&gt;Account&lt;/code&gt; model. After all, it’s the &lt;em&gt;account&lt;/em&gt; that becomes &lt;em&gt;invalid&lt;/em&gt; if there are no more administrators.&lt;/p&gt;

&lt;h2&gt;Validating in the account model&lt;/h2&gt;

&lt;p&gt;I added a custom validation and an association extension to the account model:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Account &lt; ActiveRecord::Base
  has_many :users, :dependent =&gt; :destroy do
    def admins
     self.select { |user| user.has_role?('admin') }
    end
  end

  validate :has_at_least_one_admin_user

  private

  def has_at_least_one_admin_user
    if users.admins.count &lt; 1
      errors.add(:users, "must contain at least one user of type 'admin'.")
    end
  end
end 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, if an account doesn’t have a user with the ‘admin’ role, the account will be invalid.&lt;/p&gt;

&lt;h2&gt;Triggering the account validation from the user model&lt;/h2&gt;

&lt;p&gt;Now I needed to get this validation triggered whenever someone tries to delete a user. The problem with this was, that the Account model would only be invalid &lt;em&gt;after&lt;/em&gt; the user was deleted. If I used &lt;code&gt;validates_associated :account&lt;/code&gt;, deleting the last administrator would have passed. That’s because Rails validations are run before the actual operation happens - and at this point the potentially last administrator I was going to delete still existed. E.g. if I ran &lt;code&gt;@last_admin_user.destroy&lt;/code&gt;, the associated account would still be valid at validation time, because that user actually has &lt;em&gt;not&lt;/em&gt; been deleted, yet.&lt;/p&gt;

&lt;p&gt;So I thought, the solution would be to run the validation from an &lt;code&gt;after_destroy&lt;/code&gt; callback.&lt;br/&gt;
Here, the part I struggled with was that &lt;code&gt;after_&lt;/code&gt; callbacks can only cancel transactions when they raise an error - returning &lt;code&gt;false&lt;/code&gt; in an &lt;code&gt;after_&lt;/code&gt; callback is not enough. But of course, you don’t want to end up catching errors whenever you call a simple &lt;code&gt;destroy&lt;/code&gt; on the user model.&lt;br/&gt;
It turns out, there’s a special error you can raise that doesn’t get passed on. It only causes the transaction to roll back. This error is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ActiveRecord::Rollback
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When I raise this error in the &lt;code&gt;after_destroy&lt;/code&gt; callback, the transaction will be rolled back and I do not have to worry about catching errors.&lt;/p&gt;

&lt;p&gt;The user model now looked like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class User &lt; ActiveRecord::Base
  belongs_to :account
  has_many :roles

  after_destroy  :trigger_rollback, :if =&gt; "account.invalid?"

  private

  def trigger_rollback
    account.errors.full_messages.each { |message| errors.add :account, message }
    raise ActiveRecord::Rollback
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This mechanism works beautifully for this use-case while keeping responsibilities in the models they belong.&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/10755662066</link><guid>http://devblog.vworkapp.com/post/10755662066</guid><pubDate>Wed, 28 Sep 2011 16:26:27 +1300</pubDate><category>ruby on rails</category></item><item><title>Mobile has no chance of taking off</title><description>&lt;img src="http://29.media.tumblr.com/tumblr_lryd7bcr5H1qzm7loo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Mobile has no chance of taking off&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/10542326550</link><guid>http://devblog.vworkapp.com/post/10542326550</guid><pubDate>Fri, 23 Sep 2011 13:52:22 +1200</pubDate></item><item><title>On the benefits of refactoring</title><description>&lt;p&gt;You can’t build an office block and then decide you had better put in some concrete foundations afterwards.&lt;/p&gt;

&lt;p&gt;You can, however build a large scale app and decide you want a different foundation along the way.&lt;/p&gt;

&lt;p&gt;When you start an agile project, you “pitch a tent in dirt”.&lt;/p&gt;

&lt;p&gt;E.g. write a simple app that lets users drag a ‘job’ - which only has a name and id - onto a timeline.&lt;/p&gt;

&lt;p&gt;You then itterate, turning the the tent ever so slowly into the office block ( e.g. &lt;a href="http://www.vworkapp.com"&gt;vWorkApp&lt;/a&gt; ). You get to revisit every aspect, and you &lt;strong&gt;must&lt;/strong&gt; revisit it.&lt;/p&gt;

&lt;p&gt;If you don’t, you’ll have an office block sinking into the mud.&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/10527954553</link><guid>http://devblog.vworkapp.com/post/10527954553</guid><pubDate>Fri, 23 Sep 2011 08:15:00 +1200</pubDate><category>architecture</category><category>agile</category><category>refactoring</category></item><item><title>Why Boiler is better than Robotlegs. Pt. 2</title><description>&lt;p&gt;I’m starting out with the “not terribly awesome” and perhaps even “that’s crap!” stuff. That is, you might think I’m losing my mind at this point. Remember these are things that &lt;strong&gt;I love&lt;/strong&gt; about &lt;a href="https://github.com/squeedee/Boiler"&gt;Boiler&lt;/a&gt;. You might not.&lt;/p&gt;

&lt;p&gt;I promise you, though, that the final two articles in this series will be epic. I’ll show you how to extend &lt;a href="https://github.com/squeedee/Boiler/blob/master/Steam/README.textile"&gt;Steam&lt;/a&gt; using ‘commands’ as an example. I’ll also show you how to integrate some syntactic &lt;strong&gt;sugar&lt;/strong&gt; without making the framework brittle.&lt;/p&gt;

&lt;h1&gt;Sugar be damned.&lt;/h1&gt;

&lt;p&gt;It’s &lt;strong&gt;sugar&lt;/strong&gt; that I want to discus in this post.&lt;/p&gt;

&lt;h2&gt;Sugar is usually not the same concern as the base class.&lt;/h2&gt;

&lt;p&gt;Mediator#addViewListener makes me think that Mediator &lt;strong&gt;is-a&lt;/strong&gt; view listener.&lt;/p&gt;

&lt;p&gt;Mediator#addContextListener makes me think that Mediator &lt;strong&gt;has-a&lt;/strong&gt; context bus AND &lt;strong&gt;is-a&lt;/strong&gt; contextListener.&lt;/p&gt;

&lt;p&gt;In Steam, neither is true.  Mediator &lt;strong&gt;is-a&lt;/strong&gt; class that expects to be told when a view of a specific type has been added to the stage. That’s all it is, period.&lt;/p&gt;

&lt;p&gt;Without sugar, there is no Mediator Interface, only duck typing as I explained in the previous article.&lt;/p&gt;

&lt;p&gt;It’s all about &lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;SRP&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Sugar can hide the obvious from tools.&lt;/h2&gt;

&lt;p&gt;This ones pretty fluffy, purely a matter of taste.&lt;/p&gt;

&lt;p&gt;Again with the Mediator sugar from &lt;a href="http://www.robotlegs.org/"&gt;Robotlegs&lt;/a&gt;, I would usually start typing:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;addContextListener(MyEvent.EVENT_NAME,eventNameHandler);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://www.jetbrains.com/idea/"&gt;IntelliJ&lt;/a&gt; would highlight the ‘eventNameHandler’ so I could select ‘create method’. Which is great. I can automatically stub out:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public function eventNameHandler():void {
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That’s not bad… Except if I had used:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;myContextBus.addEventListener(MyEvent.EVENT_NAME,eventNameHandler);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;IntelliJ would offer to stub out:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public function eventNameHandler(event:MyEvent):void {
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Boiler want’s us to avoid hiding language conventions. Kthx?&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/8624147633</link><guid>http://devblog.vworkapp.com/post/8624147633</guid><pubDate>Mon, 08 Aug 2011 13:14:43 +1200</pubDate><category>Boiler</category><category>Robotlegs</category><category>Architecture</category></item><item><title>Why Boiler is better than Robotlegs. Pt. 1</title><description>&lt;p&gt;Haha! That’s gunna turn some heads.. I hope.&lt;/p&gt;

&lt;p&gt;Herein I set out to explain why I’m building &lt;a href="https://github.com/squeedee/Boiler"&gt;Boiler&lt;/a&gt;. Other than the obvious fun of writing a framework, I have some very specific reasons.&lt;/p&gt;

&lt;p&gt;I could be wrong of course, Robotlegs is so good (and it’s well past the alpha stage, unlike Boiler) that it’s a tough call. However, why would I bother if I wasn’t trying to improve on something awesome?&lt;/p&gt;

&lt;h1&gt;Doubling intent&lt;/h1&gt;

&lt;p&gt;Imagine this is a mediator I just wrote:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;package views {
    public class WidgetMediator {

    [Inject]
    public var notifier:IEventDispatcher;

        private var view:Widget;

        public function register(view:Widget):void {
            this.view = view;

            view.addEventListener(MouseEvent.Click, handleClick);
        }

        public function deregister():void {
            view.removeEventListener(MouseEvent.Click, handleClick);
        }

        protected function handleClick(event:MouseEvent):void {
            notifier.dispatchEvent(event);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I consider this class to have all the markings of a mediator. It’s name ends in mediator, that should be enough… But there’s more. It’s in the views folder where a lot of folk stash their mediators. It expects to be registered against a view:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;register(view:Widget)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Despite not inheriting from a Mediator Interface, it’s a mediator. In the land of Ruby, they call it ‘duck-typing’. It looks like a duck, quacks like a duck, &lt;strong&gt;it’s a duck&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So in Boiler, we use &lt;strong&gt;conventions&lt;/strong&gt; to invert control. When you start using &lt;a href="https://github.com/squeedee/Boiler/blob/master/steam_doc.textile"&gt;Steam&lt;/a&gt;, you follow convention to describe the intent for a class. Steam, by the way, is the reference desktop framework for Boiler, like MVCS is for Robotlegs.&lt;/p&gt;

&lt;p&gt;The above mediator needs only be ‘Mapped’ using SwiftSuspenders and Steam will configure injections and view mappings ‘because it looks like a mediator’.&lt;/p&gt;

&lt;p&gt;In Boiler:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;lifetime.mapClass(WidgetMediator,WidgetMediator); // A little note on the first param later.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In Robotlegs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mediatorMap.mapMediator(WidgetMediator);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It’s a tiny difference, really, except now we don’t have to inherit from anything to look like something. Later I’ll show that we also don’t let ourselves get caught by inheriting from sugar classes.&lt;/p&gt;

&lt;p&gt;The first thing that Boiler gives you, is no more polymorphic dependencies that only serve to duplicate intent.&lt;/p&gt;

&lt;p&gt;When you want to extend the framework behavior, remove behavior, or use certain behavior in only some modules, the benefits of avoiding framework polymorphism become clear. Later on, I’ll demonstrate this with examples that extend or modify the framework.&lt;/p&gt;

&lt;h3&gt;About that first parameter&lt;/h3&gt;

&lt;p&gt;Why does SwiftSuspenders require an interface separate from the class to instance? This example is a mediator, all of it’s dependencies are injected. It’s never injected into another class. Where it’s built is where it’s stored, in a generic, testable class… So I can’t see a problem with lifetime.mapClass(widgetMediator);&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/8538689880</link><guid>http://devblog.vworkapp.com/post/8538689880</guid><pubDate>Sat, 06 Aug 2011 13:54:10 +1200</pubDate><category>Boiler</category><category>Robotlegs</category><category>Architecture</category></item><item><title>Static Controller in Robotlegs</title><description>&lt;p&gt;I’ve been away for a while in the land of the Ruby Object model and Rails. Upon my return to some Flex development, I decided that, although Robotlegs MVC ‘Controllers’ are really nice, they require too much boilerplate. One thing I found in RoR, is that although they use static controller classes with many command methods, most folk follow convention and avoid introducing wads of business logic and tightly coupling their code.&lt;/p&gt;

&lt;h2&gt;The good things about RL-MVC Commands&lt;/h2&gt;

&lt;p&gt;RL-MVC Commands enforce loose coupling. It’s really hard to end up with complex, tightly coupled controllers when every ‘action’ is a short lived class.&lt;/p&gt;

&lt;p&gt;Commands are dynamic. You can change the existing command set on the fly. I’m not sure where this is useful, I don’t take advantage of it, but that’s not to say that other people do not.&lt;/p&gt;

&lt;h2&gt;The tradeoff&lt;/h2&gt;

&lt;p&gt;With awesome power comes diminished responsibility. Yeah, that decoupling that Commands give you, removes the need for you to pay as much attention to OO and MVC best practices. Instead, you pay the price by having quite a lot of boilerplate:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One command class per ‘action’ (read: method)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I never did mind this tradeoff. Now It’s wearing thin. Our app is big, and there is a lot of boilerplate. After spending some time learning to write Ruby DSL’s it’s really grating to see that a simple and sensible idea reads so badly in code. If I was in Ruby I would have something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# controller_map.rb

map RubbishReminderEvent, PutTheRubbishOutCommand

# put_the_rubbish_out_command.rb
class PutTheRubbishOutCommand
  def initialize 
    house.nature_strip &lt;&lt; house.rubbish_bin
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Minimal boilerplate, just intention.&lt;/strong&gt; Actually, with a decent DSL, you could do away with all of the boilerplate.&lt;/p&gt;

&lt;p&gt;However if you look at Rails, events (http requests) are routed by “concept”. In the de-facto Rails convention a “concept” is a resource, but it does not need to be. The ‘routes’ tell Rails how to map incoming events to controllers.&lt;/p&gt;

&lt;p&gt;In Rails, the controllers are classes, by “concept”, with action methods. This runs the risk of being abused, and it sometimes is. However, people who &lt;strong&gt;care&lt;/strong&gt; do not make a mess of their controllers. So I decided to assume my developers are good people, and make a compromise to remove some boilerplate.&lt;/p&gt;

&lt;h2&gt;The boilerplate&lt;/h2&gt;

&lt;p&gt;As a reminder, this is the boilerplate I’m talking about&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    import ....  // boilerplate
public class PutTheRubbishOutCommand extends Command { // Boilerplate

            // Boilerplate
    [Inject] 
    public var event:TimerEvent;

            // Often repeated, not 'DRY' 
    [Inject]
    public var rubbishModel:RubbishModel;

            // The only bit of actual 'intent'
    override public function execute():void {
        rubbishModel.putRubbishBinOnNatureStrip;
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;h1&gt;Static Controller&lt;/h1&gt;

&lt;p&gt;I propose using a Static Controller. Here, “static” is an antonym of “dynamic”, not the keyword&lt;/p&gt;

&lt;p&gt;This is more like a Rails Controller which groups ‘action methods’ and reduces boilerplate:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class RubbishController extends Controller {

    [Inject]
    public var rubbishModel:RubbishModel;

    public function RubbishController() {
        addMethod(TimerEvent.RUBBISH_NIGHT, putTheRubbishOut);
        addMethod(HomeOwnerEvent.GO_TO_WORK, bringTheRubbishIn);
    }

    private function putTheRubbishOut(event:TimerEvent):void {
        rubbishModel.putRubbishBinOnNatureStrip()
    }

    private function bringTheRubbishIn(event:HomeOwnerEvent):void {
        if (!rubbishModel.rubishBinIsOnNatureStrip())
            return;

        rubbishModel.putRubbishBinRoundBack();
    }


}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I think this looks good. At this point I should apologise to Jesse Warden for admonishing him when he suggested to a conference room at FATC that it was o.k. to do this.&lt;/p&gt;

&lt;p&gt;I still think it’s not “o.k.” because if you don’t grasp the value of seperation of concerns, you will make a mockery of this approach to controllers. If you’re starting out with Robotlegs, do not use this approach!&lt;/p&gt;

&lt;h2&gt;Addendum&lt;/h2&gt;

&lt;p&gt;Extra reading: How I aim to implement the static controller&lt;/p&gt;

&lt;p&gt;The heart of a Static controller is &lt;strong&gt;Controller&lt;/strong&gt; which looks a bit like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class Controller extends Actor {

    public function dispose():void {
        eventMap.unmapListeners();
    }

    protected function addMethod(eventType:String, callback:Function, eventClass:Class = null):void {
        eventMap.mapListener(eventDispatcher, eventType, callback, eventClass);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All it does is give you the ‘&lt;em&gt;addMethod&lt;/em&gt;’ event and allows ControllerMap to tear it down via ‘&lt;em&gt;dispose&lt;/em&gt;’ as the context dies.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;addMethod&lt;/em&gt; is a similar to CommandMap#mapCommand, except it doesn’t map a class, it maps a method.&lt;/p&gt;

&lt;p&gt;Also, I need to extend Context to provide/manage ControllerMap.&lt;/p&gt;

&lt;p&gt;ControllerMap collects and disposes of Controllers. It won’t do much more than:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public function mapController(controllerClass:Class):void {
    injector.mapSingleton(controllerClass);
    controller:IController = injector.getInstance(controllerClass);
    controllers[controllerClass] = controller; // for teardown later
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I realise that some people may consider the ‘routing’ and the controller to be different responsibilities. As it stands, I cannot figure out a way of keeping routing seperate, because the Controller#actionMethods have to have a ‘thisObject’ of Controller. It would mean a really dopey looking router method like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;addMethod(TimerEvent.RUBBISH_NIGHT, RubbishController, RubbishController.putTheRubbishOut);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which would get worse when you need to enforce the event type:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;addMethod(TimerEvent.RUBBISH_NIGHT, RubbishController, RubbishController.putTheRubbishOut, TimerEvent);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;yick&lt;/em&gt;&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/6799431342</link><guid>http://devblog.vworkapp.com/post/6799431342</guid><pubDate>Thu, 23 Jun 2011 07:45:11 +1200</pubDate><category>Robotlegs</category><category>patterns</category></item><item><title>All Praise the Almighty Click!</title><description>&lt;a href="http://pckeyboards.stores.yahoo.net/mightymouse.html"&gt;All Praise the Almighty Click!&lt;/a&gt;</description><link>http://devblog.vworkapp.com/post/5746549850</link><guid>http://devblog.vworkapp.com/post/5746549850</guid><pubDate>Mon, 23 May 2011 10:19:44 +1200</pubDate></item><item><title>Agile, what it means to us.</title><description>&lt;p&gt;We’re seeing a lot of to-ing and thro-ing about Agile, it’s success and failure. There are a lot of blogs, posts and tweets which let anyone who wants to, throw it away and dismiss it out of hand.&lt;/p&gt;

&lt;p&gt;From our fledgling point of view, the point is being missed.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;To work, Agile must be all about allowing a team to do what it naturally wants to do.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s it in a nutshell. You can’t use Agile to get a team to toe the line. You can only use it to nurture the natural instincts of a team.&lt;/p&gt;

&lt;p&gt;So be very careful about the team you pick. Cultivate a team that will align itself with the business goals, often something like:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;making money, &lt;/li&gt;
&lt;li&gt;shortest path to making lots of money&lt;/li&gt;
&lt;li&gt;doing so sustainably&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The team’s instincts will likely include pride. So your business needs to add to its goals:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;making product the team can be proud of.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Then really, Agile is just a matter of trusting people. If your ecosystem cannot support trust, you will probably embrace micromanagement.&lt;/p&gt;

&lt;p&gt;We’re not being cheeky, Agile is not the only way to success or failure. But Agile is &lt;em&gt;our&lt;/em&gt; only way.&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/4990171315</link><guid>http://devblog.vworkapp.com/post/4990171315</guid><pubDate>Thu, 28 Apr 2011 07:24:00 +1200</pubDate><category>Agile</category></item><item><title>Strengthen your resolve, make your gems community tested.</title><description>&lt;a href="http://test.rubygems.org/"&gt;Strengthen your resolve, make your gems community tested.&lt;/a&gt;</description><link>http://devblog.vworkapp.com/post/4698224549</link><guid>http://devblog.vworkapp.com/post/4698224549</guid><pubDate>Mon, 18 Apr 2011 08:45:06 +1200</pubDate></item><item><title>How to name your gems</title><description>&lt;a href="http://blog.segment7.net/2010/11/15/how-to-name-gems"&gt;How to name your gems&lt;/a&gt;: &lt;p&gt;Why is it so hard to find ruby conventions? It’s the biggest aspect of the community, isn’t it?&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.segment7.net/2010/11/15/how-to-name-gems"&gt;Read the post&lt;/a&gt;&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/4613532915</link><guid>http://devblog.vworkapp.com/post/4613532915</guid><pubDate>Fri, 15 Apr 2011 08:20:17 +1200</pubDate><category>Ruby</category><category>RubyGems</category><category>Convention</category></item><item><title>Community support and IRC (introducing SQLRecord)</title><description>&lt;p&gt;A lot of my life has been spent on IRC. I got really sick of it. I got tired of the assumptions made by people meeting “anonymous” people for the first time. I include myself here, it seemed inevitable that I’d jump to conclusions without hearing someone out, and in turn made them sick of IRC too.&lt;/p&gt;

&lt;p&gt;However, in a recent expedition into making my first clean-coded, well thought out Ruby Gem, I turned to IRC for help.&lt;/p&gt;

&lt;p&gt;What I got was much more than I asked for, and it was all &lt;strong&gt;awesome-sauce&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;The Idea&lt;/h2&gt;

&lt;p&gt;We use &lt;em&gt;ActiveRecord::Base.connection.execute&lt;/em&gt; occasionally to run really fast read-only queries. Mostly for Dataviz.&lt;/p&gt;

&lt;p&gt;I don’t like it. You get a row of string-keyed string-valued hashes back from the database. All that knowledge about the schema and how to handle differently typed columns that ActiveRecord gives us, gone.&lt;/p&gt;

&lt;p&gt;Our views and view-helpers were littered with new idioms (bad habbits?) - the “Dealing with direct sql results” idioms.&lt;/p&gt;

&lt;p&gt;Not only that, but the SQL queries were in controllers! Ick.&lt;/p&gt;

&lt;h2&gt;Enter SQLRecord&lt;/h2&gt;

&lt;p&gt;My first cut of this gem is &lt;a href="https://github.com/visfleet/sql_record/blob/v0.1.0/lib/sql_record.rb"&gt;SQLRecord v 0.1.0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was my first ever DSL in Ruby, and I thought, quite idiomattic.&lt;/p&gt;

&lt;h2&gt;Time to doc.&lt;/h2&gt;

&lt;p&gt;So I started documenting. It was annoying me that my Yard Index was showing a module ClassMethods rather than showing them as Class Methods of the module that used the &lt;strong&gt;include-to-extend&lt;/strong&gt; idiom.&lt;/p&gt;

&lt;p&gt;So I went to &lt;a href="irc://irc.freenode.net/yard"&gt;#yard at irc.freenode.net&lt;/a&gt; channel to ask about indicating that this module’s methods belonged to another. &lt;a href="http://gnuu.org/"&gt;Loren Segal&lt;/a&gt; was there and told me there wasn’t any way of munging the docs…&lt;/p&gt;

&lt;h2&gt;Extending themselves to the community.&lt;/h2&gt;

&lt;p&gt;Here’s the beginning of that discussion:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;[08:50] &lt;squee-d&gt; Is there a trick in yard to make Module docs (like ClassMethods) look like those of the parent Module?&lt;br/&gt;
  [08:51] &lt;@lsegal&gt; you mean like get ClassMethods to be interpreted as a set of class methods? Unfortunately not really&lt;br/&gt;
  [08:52] &lt;squee-d&gt; yah thats what i meant&lt;br/&gt;
  [08:53] &lt;squee-d&gt; &lt;a href="http://yehudakatz.com/2009/11/12/better-ruby-idioms/"&gt;http://yehudakatz.com/2009/11/12/better-ruby-idioms/&lt;/a&gt; I’m going to re-read this until i get it.&lt;br/&gt;
  [08:54] &lt;@lsegal&gt; indeed, that’s a good one. I’m not too fond of ClassMethods either&lt;br/&gt;
  [08:55] &lt;@lsegal&gt; poor docs being one reason why&lt;br/&gt;
  [08:56] &lt;@lsegal&gt; ClassMethods usually translates to “i have a poorly named mixin”&lt;/squee-d&gt;&lt;/squee-d&gt;&lt;/squee-d&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://yehudakatz.com/2009/11/12/better-ruby-idioms/"&gt;Yehuda’s post&lt;/a&gt; was haunting me but I wasn’t understanding it.&lt;/p&gt;

&lt;p&gt;For the next 2 hours, off and on, Loren gave me a code review that changed my world view.&lt;/p&gt;

&lt;p&gt;I would say that he &lt;strong&gt;improved Ruby by improving one passionate developers view of Ruby&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I now believed that good OO Principles were entirely practicable within this magical wonderland language called Ruby, where all ropes are long and could hang you, your family, and your-pit bull, without breaking a sweat.&lt;/p&gt;

&lt;p&gt;Now I had a new perspective, &lt;a href="https://github.com/visfleet/sql_record/tree/v1.0.4"&gt;a better Gem&lt;/a&gt; and I was pretty sure I was coding what I needed, without over-cooking it.&lt;/p&gt;

&lt;h2&gt;But wait, there’s more!&lt;/h2&gt;

&lt;p&gt;So one thing that happened as I re-factored, was a mistaken version bump into the 1.0s. Not where I meant to be. I trotted off to &lt;a href="irc://irc.freenode.net/rubygems"&gt;#rubygems at irc.freenode.net&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I got an answer about using gem ‘yank’ to remove a gem but then:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;@drbrain&gt; you should not be embarrassed by releasing early and often&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok then. I broke semantic versioning but I was hitting it hard and “showing my working”. Math education really does have value!&lt;/p&gt;

&lt;p&gt;A little later, out of the blue, and not related to my versioning problem, but the code itself, someone said:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;erikh&gt; doesn’t AR::Base.find_by_sql solve this?&lt;/erikh&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok! Here we go, the IRC I know and hate. Someones about to tell me I’m doing it wrong without background information…&lt;/p&gt;

&lt;p&gt;Well no not really. &lt;a href="https://github.com/erikh"&gt;Erik Hollensbe&lt;/a&gt;, as it turns out, had an abiding interest in what I was doing and made me argue the approach I was using. &lt;strong&gt;Moar gravy for my awesome-sauce&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s it. Thankyou to the community for being open minded, passionate and brilliant. I’ve had a very good week.&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/4532718402</link><guid>http://devblog.vworkapp.com/post/4532718402</guid><pubDate>Tue, 12 Apr 2011 08:22:40 +1200</pubDate><category>Ruby</category><category>IRC</category><category>Rubygems</category><category>SQLRecord</category></item><item><title>Ruby DSL post that answers (my) age old (2 days in reality) question</title><description>&lt;a href="http://ruby-lang-love.blogspot.com/2010/08/slick-code-with-simple-dsls-thanks-to.html"&gt;Ruby DSL post that answers (my) age old (2 days in reality) question&lt;/a&gt;: &lt;p&gt;Ruby DSL blocks need access to DSL methods. But which scoping to use?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Farm.new do 
  animal :kitten
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Farm.new do |farm|
  farm.animal :kitten
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;TL;DR? You can support both!&lt;/p&gt;

&lt;p&gt;Go read &lt;a href="http://ruby-lang-love.blogspot.com/2010/08/slick-code-with-simple-dsls-thanks-to.html"&gt;Rubylove’s article&lt;/a&gt;&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/4027985693</link><guid>http://devblog.vworkapp.com/post/4027985693</guid><pubDate>Wed, 23 Mar 2011 08:26:00 +1300</pubDate></item><item><title>New Flex Monkey! (Reloaded)</title><description>&lt;a href="http://www.gorillajawn.com/wordpress/2011/02/24/flexmonkey-reloaded-beta/"&gt;New Flex Monkey! (Reloaded)&lt;/a&gt;</description><link>http://devblog.vworkapp.com/post/3567869633</link><guid>http://devblog.vworkapp.com/post/3567869633</guid><pubDate>Tue, 01 Mar 2011 09:07:23 +1300</pubDate></item><item><title>Position Vacant - Rails Focused Technical Lead Role</title><description>&lt;p&gt;&lt;strong&gt;Visfleet&lt;/strong&gt; is looking for a &lt;strong&gt;certain someone&lt;/strong&gt; to join our &lt;strong&gt;Agile team&lt;/strong&gt; to develop our world class &lt;strong&gt;product&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Warning, bullet points follow.&lt;/p&gt;

&lt;h2&gt;That someone:&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;Has a love affair with RubyOnRails that they’re not ashamed to confess to.&lt;/li&gt;
&lt;li&gt;Is looking for a senior role where they can help guide the architecture and vision of the product.&lt;/li&gt;
&lt;li&gt;Enjoys multi-disciplinary work, like say, getting involved in Flex and Mobile development.&lt;/li&gt;
&lt;li&gt;Is all about the Agile.&lt;/li&gt;
&lt;li&gt;Wants to release often.&lt;/li&gt;
&lt;li&gt;Wants to focus on quality code.&lt;/li&gt;
&lt;li&gt;Likes to see users truly enjoy working with their product.&lt;/li&gt;
&lt;li&gt;Can work in our Parnell Office, Auckland, New Zealand. (We will help with work/residency Visa’s for the right applicant)&lt;/li&gt;
&lt;li&gt;Loves to mentor and be mentored.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;The team:&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;Love RubyOnRails and Flex.&lt;/li&gt;
&lt;li&gt;Enjoy Multi-disciplinary work.&lt;/li&gt;
&lt;li&gt;Are all about Agile.&lt;/li&gt;
&lt;li&gt;Come from diverse backgrounds, and love it.&lt;/li&gt;
&lt;li&gt;Are proud of what they achieve, each and every release. And they release often!&lt;/li&gt;
&lt;li&gt;Consists of 7 developers and 1 tester.&lt;/li&gt;
&lt;li&gt;Wants to stay small and focused.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Learn more on &lt;a href="http://devblog.vworkapp.com"&gt;this blog&lt;/a&gt;, our &lt;a href="http://blog.vworkapp.com"&gt;business blog&lt;/a&gt;, and &lt;a href="http://www.vworkapp.com/about.html"&gt;our staff page&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also see our &lt;a href="http://www.kanbancam.com/"&gt;Kanban Board&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;The product:&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;Is the worlds best dispatch software.&lt;/li&gt;
&lt;li&gt;Is web deployed, with clients for iPhone and Android.&lt;/li&gt;
&lt;li&gt;Is simple and easy to use (honestly, that’s not hyperbole)&lt;/li&gt;
&lt;li&gt;Solves real problems for a real demographic.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is deployed in the cloud.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.vworkapp.com/index.html"&gt;Learn more…&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Visfleet:&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;Located in Parnell, Auckland.&lt;/li&gt;
&lt;li&gt;Expanding into Australia and the USA this year.&lt;/li&gt;
&lt;li&gt;A team of about 20. &lt;/li&gt;
&lt;li&gt;Has a management and executive team that value continuous delivery and clean code! (Seriously OMG right?)&lt;/li&gt;
&lt;li&gt;The business &lt;strong&gt;IS&lt;/strong&gt; the team.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Want to know more, visit our &lt;a href="http://www.vworkapp.com/index.html"&gt;web site&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Want to apply? Contact us on &lt;a href="mailto:jobs@visfleet.com?subject=Regarding%20Position%20Vacant%20-%20Rails%20Focused%20Technical%20Lead"&gt;jobs@visfleet.com&lt;/a&gt;&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/3492161922</link><guid>http://devblog.vworkapp.com/post/3492161922</guid><pubDate>Fri, 25 Feb 2011 13:21:00 +1300</pubDate></item><item><title>Extract Responsibility Refactoring.</title><description>&lt;p&gt;In &lt;a href="http://martinfowler.com/books.html#refactoring" title="Refactoring Book"&gt;Martin Fowler’s “Refactoring”&lt;/a&gt; he introduces the “&lt;a href="http://www.refactoring.com/catalog/extractClass.html" title="Extract Class"&gt;Extract Class&lt;/a&gt;” refactoring. I love this refactoring pattern and I use it all the time.&lt;/p&gt;

&lt;p&gt;This refactoring is (unless im sorely mistaken) the most important one for the &lt;a href="http://www.objectmentor.com/resources/articles/srp.pdf" title="Single Responsibility Principle"&gt;SRP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Because of this intimacy with the SRP, I think there is an umbrella refactoring, called “Extract Responsibility” with two concrete methods for achieving it:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Extract Component (formerly Extract Class)&lt;/li&gt;
&lt;li&gt;Extract Process (sometimes &lt;a href="http://www.refactoring.com/catalog/formTemplateMethod.html" title="Form Template Method"&gt;“Form Template Method”&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Extract Responsibility&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;You have one class responsible for the work that should be done by two.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decide if the extra responsibility is encapsulated as a Component (Has-A) or a Process (IoC)&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;Extract Component&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;You have one class with an additional responsibility that exhibits compositional behaviour&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a new class and move the relevant fields and methods from the old class into the new class&lt;/strong&gt; (lifted directly from &lt;a href="http://www.refactoring.com/catalog/extractClass.html" title="Extract Class"&gt;Extract Class&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The new class is a component if all it takes to make the refactoring, is to move methods. In my experience you are ‘Extracting A Component’ if the original classes’ data easily fits into a “Has-A” relationship.&lt;/p&gt;

&lt;h2&gt;Extract Process&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;You have two methods in subclasses that perform similar steps in the same order, yet the steps are different.&lt;/em&gt; (lifted directly from &lt;a href="http://www.refactoring.com/catalog/formTemplateMethod.html" title="Form Template Method"&gt;“Form Template Method”&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a new class, add process hooks in the new class and use those to call on the original classes actions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;OK so here is the crux of the matter. There are classes that still have too much responsibility, but it’s not in a ‘Has-A’ relationship. These classes have a ‘process’. These classes often present themselves in sets. Usually you will find two classes doing the exact same thing with moderately different behaviour.&lt;/p&gt;

&lt;p&gt;The most suitable term for this extraction is “&lt;a href="http://en.wikipedia.org/wiki/Inversion_of_control" title="Inversion Of Control"&gt;Inversion of Control&lt;/a&gt;”. Please don’t think I mean DI. DI, especially automated DI, is “Orthogonal Control” in my mind (topic of another post I must write).&lt;/p&gt;

&lt;p&gt;The most common way I’ve seen of inverting control for a class or set of classes is the &lt;a href="http://www.refactoring.com/catalog/formTemplateMethod.html" title="Form Template Method"&gt;Form Template Method Refactoring&lt;/a&gt;. There are probably quite a few other methods for achieving IoC, including utilizing annotations.&lt;/p&gt;

&lt;p&gt;The one I prefer is the &lt;a href="http://martinfowler.com/bliki/FluentInterface.html" title="Fluent Interface"&gt;Fluent Interface&lt;/a&gt;, and a beautiful example of IoC in fluent interfaces is &lt;a href="https://github.com/darscan/robotlegs-extensions-oil/blob/master/src/org/robotlegs/oil/async/Promise.as" title="Shaun Smith's 'Promise'"&gt;Shaun Smith’s Promise Class&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In general I prefer Fluent Interfaces over Template Methods because they turn an ‘Is-a’ into a ‘Has-a’, providing far less coupling, and allowing for more than one ‘Process’ to be utilized by any given class.&lt;/p&gt;

&lt;p&gt;This actually makes the new Fluent class a “has-a” relationship, so how does this differ from ‘Extract Component’? - You are not extracting data, you are extracting common behavior.&lt;/p&gt;

&lt;p&gt;There is one downside to Fluent Interfaces: Language support.&lt;/p&gt;

&lt;p&gt;In languages like Actionscript 3, you cannot delegate methods with static typing. This means that the callbacks you give your fluent interface are not compile time checked. In my next ‘Actionscript 4’ article I’ll talk more about static typed delegates and how much I think we need them in the language.&lt;/p&gt;

&lt;h2&gt;Finally&lt;/h2&gt;

&lt;p&gt;My apologies that my writing is not succinct. Writing is a craft I need to take more time to master. So please, feedback, opinions and constructive criticism!&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/3407775542</link><guid>http://devblog.vworkapp.com/post/3407775542</guid><pubDate>Mon, 21 Feb 2011 08:36:05 +1300</pubDate><category>Refactoring</category><category>Architecture</category></item><item><title>Musings on AS4 - Part 1, Safe Navigation, Safe Exclusion</title><description>&lt;p&gt;So I had surgery 2 nights ago. Routine Gall bladder thing. But the pain killers, namely morphine, keep me awake, contrary to their typical side effects. This left me up all night, in a hospital room, with such a calm mind and strange thoughts, that my desires for Actionscript began to crystalise.&lt;/p&gt;

&lt;p&gt;These are meant to be idea’s to argue over, so please do comment.&lt;/p&gt;

&lt;h2&gt;Safe Navigation&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://groovy.codehaus.org/Operators#Operators-SafeNavigationOperator%28%3F.%29"&gt;Groovy’s Safe Navigation Operator&lt;/a&gt; is pretty straight forward:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var a:String = b?.c?.e
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If b evaluates to null, a is null.
Same for c.&lt;/p&gt;

&lt;p&gt;It’s wonderful. I really don’t think I need to use Null Objects as often as I do.&lt;/p&gt;

&lt;h2&gt;Safe Exclusion&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en"&gt;“Alan Kay’s meaning of OOP”&lt;/a&gt; and ObjC’s message passing got me thinking about thorough bi-directional decoupling. In the vWork application code, we have a considerable number of modules, which use a notifier bus (Robotlegs Modular context) to pass messages between modules. To properly decouple ‘Module A’ from ‘Module B’, I ended up with something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module.a.events.IRaiseThisEventOnTheBus
module.b.events.IExpectThisEventToBeRaised
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or to be more concrete:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module.map.workerSelectedEvent
module.workerManager.selectWorkerEvent
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and then I have a ‘master’ module manage the coupling. It listens for ‘workerSelectedEvent’ and fires the selectWorkerEvent. Now neither module has an import from the other…&lt;/p&gt;

&lt;h3&gt;The glue module still couples.&lt;/h3&gt;

&lt;p&gt;And this is the rub. My master module (usually the application boot module) has knowledge (read: imports) of both modules. Thats not a truly decoupled program.&lt;/p&gt;

&lt;h3&gt;Dynamic events&lt;/h3&gt;

&lt;p&gt;So the obvious way to get true decoupling is to use untyped messages. Like ruby, or ObjC might do. It works because a module can dissapear, and the other ‘dependent’ module is just listening for a magic string or symbol that never arrives.&lt;/p&gt;

&lt;p&gt;I don’t like this approach, because I &lt;strong&gt;like&lt;/strong&gt; type-safety.&lt;/p&gt;

&lt;h3&gt;Type-Safe events can be missing&lt;/h3&gt;

&lt;p&gt;My solution is to allow namespaces and classes to be missing. A kind of null-safety if you will. I can only describe it in code:&lt;/p&gt;

&lt;p&gt;Describe an event class:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;package module.map.events {

  import flash.events.*  

  public class WorkerSelectedEvent extends Event {
     ... event boilerplate ...
     public function get payload():TypeSafeThing {
       return _payload;
     }
  } 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And ‘Maybe’ consume it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;package module.workerManager.config {

  use module.map.events.WorkerSelectedEvent;
  use module.map.TypeSafeThing; 

  public class Config {
    ... stuff ...
    public function configWorkerListener() {
      if (WorkerSelectedEvent is _UndefinedClass)
        return;

      bus.addEventListener(WorkerSelectedEvent.SELECTED, selectedHandler);
    }
  } 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Where ‘use’ is defined instead of ‘import’, the compiler will find the Class, but if it cannot, it will replace it with an instance of _UndefinedClass, which has no methods or behaviour, it’s just a marker.&lt;/p&gt;

&lt;p&gt;I would quickly replace EventDispatchers with something like Rob Penner’s signals (although I want to see c# style delegates, which I’ll cover in part 2). A signal/delegate message passing system could happily accept an _UndefinedDelegate and make most of this decoupling transparent.&lt;/p&gt;

&lt;p&gt;I suspect ‘use’ would be the defacto when specifying message classes/delegates.&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/3104118378</link><guid>http://devblog.vworkapp.com/post/3104118378</guid><pubDate>Sat, 05 Feb 2011 02:01:00 +1300</pubDate><category>actionscript</category><category>as4</category></item><item><title>The Meaning Of Object Oriented</title><description>&lt;a href="http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en"&gt;The Meaning Of Object Oriented&lt;/a&gt;</description><link>http://devblog.vworkapp.com/post/2910410940</link><guid>http://devblog.vworkapp.com/post/2910410940</guid><pubDate>Tue, 25 Jan 2011 06:50:06 +1300</pubDate></item><item><title>Dominic Graefen introduces a Flex/Flash Buildr Extension </title><description>&lt;a href="http://devboy.org/2011/01/21/build-like-you-code-supporting-as3/"&gt;Dominic Graefen introduces a Flex/Flash Buildr Extension &lt;/a&gt;: &lt;p&gt;Dominic Graefen (&lt;a href="http://twitter.com/#!/search/devboy_org"&gt;@devboy_org&lt;/a&gt;) introduces a Flex/Flash extension for &lt;a href="http://buildr.apache.org/"&gt;Buildr&lt;/a&gt;.
I recommend Buildr over Maven or other declarative build/dependency systems. Give it a go :)&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/2899647411</link><guid>http://devblog.vworkapp.com/post/2899647411</guid><pubDate>Mon, 24 Jan 2011 12:29:00 +1300</pubDate><category>actionscript</category><category>flex</category><category>compiler</category><category>buildr</category><category>ruby</category></item><item><title>Robotlegs Bootstrap Actor</title><description>&lt;p&gt;I’m sharing the following Bootstrap Actor class, which simplifies bootstrap sequencing in  &lt;a href="http://www.robotlegs.org/"&gt;Robotlegs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I figure it has some value because &lt;a href="http://www.xxcoder.net"&gt;Stray&lt;/a&gt;, who has a fairly similar programming ethos to me, &lt;a href="http://knowledge.robotlegs.org/discussions/solutions/10-feature-composition-by-bootstrap-command#comment_4776689"&gt;see’s some merit in it&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Usage first.&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Trigger the bootstrap in your context&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;override public function startup():void {
    commandMap.mapEvent(ContextEvent.STARTUP_COMPLETE, BootstrapCommand, ContextEvent);
    super.startup();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Which calls the BootstrapCommand&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import org.robotlegs.mvcs.Command;

public class BootstrapCommand extends Command {

    override public function execute():void {
        injector.mapSingleton(ConfigurationSequence);
        injector.getInstance(ConfigurationSequence).step();
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Then implement the sequence&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class ConfigurationSequence extends AbstractSequencer {

    override protected function configure():void {
        addStep(ConfigureWorkersModelCommand);
        addStep(ConfigureScalesModelCommand);

        ... yadda yadda ... 

        addStep(ConfigureJobDraggingModel);
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What happens is that the line in the bootstrap&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;injector.getInstance(ConfigurationSequence).step();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;instances the Sequencer and tells it to run the next step, which in this case, is the first one.&lt;/p&gt;

&lt;p&gt;Each command added with ‘addStep’ is added as a command mapping which responds to a &lt;a href="https://gist.github.com/783251#file_sequence_step_event.as"&gt;SequenceStepEvent&lt;/a&gt; with a named type. This is not conventional behavior for an event, but it works really well in this context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finally, a sequenced command looks a bit like this:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class ConfigureScheduleHeaderViewCommand extends Command {

    [Inject]
    public var event:SequenceStepEvent;

    override public function execute():void {
        mediatorMap.mapView(TimelineView, TimelineMediator);
        ... yadda yadda ...

        event.step();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The event.step causes the next item to be run.&lt;/p&gt;

&lt;h2&gt;Source Code&lt;/h2&gt;

&lt;p&gt;The sequencer gets the addStep() and configure() methods from &lt;a href="https://gist.github.com/783251#file_abstract_sequencer.as"&gt;AbstractSequencer.as&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You also need the &lt;a href="https://gist.github.com/783251#file_sequence_step_event.as"&gt;SequenceStepEvent.as class&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Options&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bootstrap command and context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You &lt;em&gt;could&lt;/em&gt; merge BootstrapCommand into the context. I prefer to overdo &lt;a href="http://www.objectmentor.com/resources/articles/srp.pdf"&gt;SRP&lt;/a&gt; than underdo it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automatically step&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of specifying event.step() in each sequence command, you could modify &lt;a href="https://gist.github.com/783251#file_abstract_sequencer.as"&gt;AbstractSequencer#executeNextStep&lt;/a&gt; like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;private function executeNextStep():void {
    var classFQN:String = steps.shift();
    var event:SequenceStepEvent = new SequenceStepEvent(classFQN, this);

    dispatch(event);

    step();
}
&lt;/code&gt;&lt;/pre&gt;</description><link>http://devblog.vworkapp.com/post/2798938177</link><guid>http://devblog.vworkapp.com/post/2798938177</guid><pubDate>Tue, 18 Jan 2011 09:05:00 +1300</pubDate><category>Robotlegs</category><category>Bootstrap</category></item><item><title>Have you seen our Kanban Camera?</title><description>&lt;a href="http://www.kanbancam.com/"&gt;Have you seen our Kanban Camera?&lt;/a&gt;: &lt;p&gt;Our kanbancam runs 24/7 (with archives) at &lt;a href="http://www.kanbancam.com/"&gt;&lt;a href="http://www.kanbancam.com/"&gt;http://www.kanbancam.com/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the view of our &lt;a href="http://www.infoq.com/articles/hiranabe-lean-agile-kanban"&gt;Kanban&lt;/a&gt; wall. To the right of frame you can see our information &lt;a href="http://wiki.hudson-ci.org/display/HUDSON/eXtreme+Feedback+Panel+Plugin"&gt;radiator &lt;/a&gt;showing our &lt;a href="http://hudson-ci.org/"&gt;Hudson CI&lt;/a&gt; status.&lt;/p&gt;</description><link>http://devblog.vworkapp.com/post/2390222069</link><guid>http://devblog.vworkapp.com/post/2390222069</guid><pubDate>Tue, 21 Dec 2010 07:17:41 +1300</pubDate></item></channel></rss>

