10:59 am, squeedee
 Comments
Text
List Model-Service Architecture with Robotlegs

I’m currently looking at our services and model tier architectures. I’m focusing right now on the most common requirement of the client model-service tiers at Visfleet:

  • Maintain a client side representation of collection resources (Lists of like information)
  • Keep the list server-canonical (allow the server to provide the most up-to-date state as often as possible)
  • Expose standard REST operations for List, Show, Update, Create, Delete, New, Edit
  • Expose resource specific methods (RPC when needed)

So I was looking for a prescription, that as usual, kept my responsibility-count-per-class down near one.

What follows is my first draft. (Embiggen)

Class Diagram

Note: IUpdateable is the only non-metaclass in this diagram.

service.load

So in this example I support service.load() which fetches the state of the whole list, or part of the list, from the server. The description of sequence that follows works as easily for any service request that results in a result record coming back from the server.

  1. service.load() requests a list form the server.
  2. service iterates over the service results
    1. Uses voFactory.create() to create a new concrete VO
    2. Parses the server result into the VO
    3. Adds the VO to a payload.
  3. service emits a signal that it has results, which carries the payload it just created.

controller (HandleResultCommand)

Typical Robotlegs behaviour here:

  1. HandleResultCommand calls listModel.update() passing the payload of VOs

listModel.update()

The list model needs to ensure that its representation of the list is updated by the incoming payload

  1. Iterates over the payload
    1. Adds VO to list if it’s new (not in list)
    2. Updates existing list VO if it’s an update (in list)

To update a VO, listModel depends on IVO being IUpdateable. This could be a responsibility of the ListModel itself, I’m still not sure which is more OO Savvy.

In my opinion, a broadly updateable VO is a requirement of the Flex framework. Collection types in Flex work best if VO object references don’t change. So do the collection-aware components.

The Gap

Usually at this point, someone wants to edit a VO. We don’t modify server-canonical VO’s in our apps, we clone them. We edit the clone, and actually share the clone as an ‘EditableModel’ so our whole app has access to the current VO under edit.

This is a perfect arrangement, however, I’m stuck. Making IVO ICloneable is not possible, I could only make VO ICloneable. If i move the IUpdateable respnsibility to ListModel there’s now a gap for ICloneable, but I’m not pleased with making an unassociated refactor a requirement.

If I introduce my EditModel at this point however, I do get a way around this that makes sense.

Welcome EditModel

(Embiggen) Class Diagram

I’ve dropped some components to make this clearer.

EditModel is introduced. It maintains the currently ‘under edit’ VO which is a clone. It uses ICloneable a little like a marker interface to do this. However it does require the VO to implement clone().

Do you think I should be making the effort to make ICloneable purely a marker and have a CloneStrategy?

Please feel free to comment, once you are aware of my usual disclaimers


04:10 pm, squeedee
 Comments
Text
On Robotlegs UI Architectures

There are now Caveats to all my posts.

I am considering everything in this post from the point of view of a N-Tier RIA developer’s point of view.

The Robotlegs MVCS presents a myriad of ways you can work with your tiers, without adding one line of extra framework code or departing from the Best Practices. Then there are the few presentation model mods I’ve seen around, such as Elad Elrom’s.

I quite like the “Robotlegs is the presentation model” one we use at Visfleet. Below, I give a little bit of backstory and explain why I like it so.

“MVC”

I find that the original beauty of MVC is somewhat lost in most breakdowns of MVC-like architectures. I have to wonder if I’m missing something.

Originally the “View” of MVC was a Component, The original SmallTalk MVC was component oriented. From Fowler’s UI Architecture Article:

At this point I should stress that there’s not just one view and controller, you have a view-controller pair for each element of the screen, each of the controls and the screen as a whole.

There are reasons this approach died off and isn’t considered practical. Noteably, when the components are generic (yay re-use) and encapsulate their own modelling. For example, a checkbox has it’s own selection state and transition modelling. All you get as a consumer is a public interface (on the “View” no less) consisting of properties (e.g.: checked), methods and signals (e.g.:VALUE_COMMIT).

However there is a beauty to the idea of having control/model support for these component views in your MVC-like architecture. This is something I’m a proponent of. Verbs like “select”, “move”, “reorient”, “announce”, “publish”, “change”, “commit”, “save” etc can all become adjectives of state: “Jobs[1] is selected”, “task is running”, “person is facing east”.

I consider a lot of what most would call ‘view state’ (something kept by view, mediator or presenter) is in fact domain modelling.

Domain Modelling

Again from Fowler’s UI Architecture Article:

The idea behind Separated Presentation is to make a clear division between domain objects that model our perception of the real world, and presentation objects that are the GUI elements we see on the screen. Domain objects should be completely self contained and work without reference to the presentation, they should also be able to support multiple presentations, possibly simultaneously.

I worry that the domain modelling found in the client-tier of most N-Tier applications (read database backed with a server encapsulating business logic) is often treated as a model of the business logic.

Certainly there is a good case to model some business logic in the client for speed and responsiveness, networks aren’t terribly fast compared to my computer’s bus. However that “business logic” being modelled is actually a part of the client domain model. It should be considered a utility and not actual Business Domain Modelling.

Let’s reiterrate that through example.

The business tier (server) says that:

  • A “Job” may transition state from “started” to “finished” or to “not started”.
  • A “Job” can not transition from “Started” to “Deleted” (you have to finish the job or back out of it before removing it)

When enforced on the business tier, this is “Business Logic” or “Business Domain Modelling”

When mimicked in the client tier, this is “Client Domain Modelling”. It is not:

  • Canonincal. So I’m calling it untrusted
  • Business Logic. Let’s not have it in two places.

Client Domain Models in N-Tier application clients are there to serve the purpose of presenting the business to the user

What I take away from this is:

  • A “Start” method is a domain model action.
  • selectedItem is domain model state.
  • runningJobs is domain model state.
  • etc…

To put it another way, I see my whole Robotlegs MVCS stack as one giant ‘Presentation Model’

Re-tiering feels pointless

What a lot of people do in their presenters and mediators is have a local state and message bus. This feels awkward to me. Suddenly I’m without a prescription, and frankly it’s really easy for me to write crap again. I can fill my mediator or presenter with awkward code that unsuprisingly is often best served by the MVC pattern.

I could treat my mediator as the context for another Robotlegs stack, however there is one clear drawback to this: Views, with their own concerns, cannot change containment easily. I explain this with the “Doorbell Model” later.

One context to rule them all

Or most of them… There’s lots of good reasons to use subcontexts, but within a context, I want to use a single MVCS 4-Tier.

I mediate as many components as I can, it gives me some of the elegance that the original MVC had. Each component action is mapped to a command, the command changes state in my modelling in some way, the mediator and view ensure they represent the new state. Again, I’ll outline this in the “Doorbell Model”

If I want to ‘genericise’ a component, and thus limit other users to it’s view’s public interface (as with most UIComponents), then I still create a robotlegs 4-tier stack and pass in dependencies via the view’s public interface. Then the context for the component uses these values as injection mappings (often named value mappings). I don’t do this very often mind you, a single context doesn’t cause me any real pain. Sub contexts might make for less clutter and I look forward to investigating those further.

The Doorbell Model

A simple analogy for why I don’t want any more tiers than the 4 in MVCS.

First, the views

  • A House is composed of a roof, a floor, and walls.
  • Walls are composed of Mortar, Bricks, Windows, Adornments and Doors
  • Doors have Adornments.
  • Example Adornments are: Lights, Doorknockers, Doorbells, Plaques etc..

A doorbell, where you might find it.

I’ve seen Doorbells on Doors, on the Wall beside Doors , and even at the back of a House (for a teenage boy’s mates to ring late in the evening.)

My original design might call for the Doorbell to be beside the frontDoor, thus contained by the frontWall, in turn contained by the house.

This frontDoorBell could be mediated by House’ or Door’s mediator. But why? Why not put a mediator on DoorBell. Then when I go to put a DoorBell on the backWall, and move the frontDoorBell to the frontDoor itself, nothing needs to change.

I almost imagine the DoorBell’s mediator to be a little circuit that hooks it to the wire on the House’ event bus.

An identifiable doorbell

Did you notice the arrival of the DoorBell on the backWall. This puppy makes it interesting. The event bus wants to ring two different bells, one for the teenageKidsRoom.bell and one for the hallway.bell. How would we identify the messages coming from these objects? That’s easy, the parent container of the DoorBell can inform it of it’s location (or the doorbell could ask the parent, it’s not an issue we need to care about right now).

The DoorBell.location property can be used to identify it’s position within views. This is appropriate intimacy and requires nothing but an obvious refactor to introduce it.

All those classes!

This approach to architecting my UI means that I have a proliferation of class definitions, and all within the convention of /model /view /controller /events /service. That’s OK. I compartmentalise component of the system by namespaces. Take a look at our namespace-prescription (living document) for Visfleet’s vWork product.

RFC

If you think I need to clear up anything or ammend anything or consider something, please comment. I crave peer input :)


08:49 am, squeedee
 Comments
Text
Verbose is a dirty word

I’m not saying verbose should be a dirty word, just that it does have a pejorative meaning. If you’ve used *nix command line tools often enough, you’ll know that -v is often used as a flag for “verbose”. This usually ends up in some useful information coming out of the log or stdout. -vvv usually means “very verbose” and too much information pours out to be of any use. And this is the risk:

If verbose is your end-goal, then the more verbose you are, the better.

Right? I mean that makes sense. If “quality” is your end-goal, then more and more quality is a thing to strive for. Same goes for “agile”, “fair”, “loyal”, “just”. All these words suggest that the more you pile it on, the better. This is not true of verbose. Keep getting verbose, and in fact, you just get more noise.

I’m probably nitpicking this to death, but I’m only doing so, now, because I think I have a better quality to strive for:

Expressiveness

Really in our code, we wan’t to be more expressive. We want every line we read to convey it’s meaning.

If you check out expressive at dictionary.com there’s also a nice set of synonyms:

Synonyms: These adjectives mean effectively conveying a feeling, idea, or mood: an expressive gesture; an eloquent speech; a meaningful look; a significant smile.

I think eloquent is a good word too, it usually conveys meaning in a terse manner. That’s right, less verbose, just enough meaning and no more.

Readable Code

This code is readable, but not expressive:

public class EmployeeModel {
    ....
    public function save():void {
        if ((editingEmployee.name.length > 0) && (employees.checkUnique(editingEmployee.ssid))) {
            employees.comit(editingEmployee);
        }
    }
    ...
}

Expressive Code

So now I refactor it.

public class EmployeeModel {
    ....
    protected function employeeIsValid(employee:EmployeeVO):Boolean {
        return ((employee.name.length > 0) && employees.checkUnique(employee.ssid))
    }

    public function save():void {
        if (!employeeIsValid(editingEmployee)
            return;

        employees.comit(editingEmployee);
    }
    ...
}

I use a guard clause for starters because they convey intent more clearly.

Then I extract the method (all praise ctrl-alt-m in IntelliJ IDEA) employeeIsValid(). This gives the guard more meaning, and also gives the extracted condition more meaning. It’s a win-win.

Verbose Code

Now, is this the following code more expressive or more verbose?

public class EmployeeModel {
    ....
    protected function employeeNameIsValid(employee:EmployeeVO):Boolean {
        return employee.name.length > 0;
    }

    protected function employeeIsValid(employee:EmployeeVO):Boolean {
        return (employeeNameIsValid(employee) && employees.checkUnique(employee.ssid))
    }

    public function save():void {
        if (!employeeIsValid(editingEmployee)
            return;

        employees.comit(editingEmployee);
    }
    ...
}

I extract the name comparison (pretend for a moment that it couldn’t be done in the VO) - employeeNameIsValid().

This is not too bad, I think. It expresses that an employeeName that’s greater than 0 chars long is valid.

However this is easily inferred from the previous example, because the test is inside ‘employeeIsValid’ - It would read just as well, and so I wouldn’t bother with this extra step. At least, not until it got more complex. Remember, most refactorings are bidirectional.


02:49 pm, jonathan-visfleet
1 note
 Comments
Text
Install pg gem via Bundler on OSX Snow Leopard

I encountered three problems installing the Postgres ruby gem (pg) when using Bundler to install all the gems for a project on my OSX Snow Leopard 10.6 machine.

Firstly, the gem fails to build on Snow Leopard when you use the binary version of Postgres that is distributed by Enterprise DB. To work around this, the Postgres binaires need to be installed using Mac Ports.

Secondly, the pg gem must be installed using additional bash environment variables.

Thirdly, every time you run bundle install, the current version of Bundler hard re-installs all gems listed in ./Gemfile. This means that even if you install the pg gem correctly by hand, bundler will still try to reinstall it.

All three are resolved as below, in my case I am using Postgres 8.4.

Install postgres from Mac Ports

sudo port install postgres84

Include the postgres binaries in the PATH environment variable

export PATH=/opt/local/lib/postgresql84/bin:${PATH}

Then run bundle install with the all-important arch flag

env ARCHFLAGS="-arch x86_64" bundle install

Edit: removed sudo from bundle command.


08:38 am, squeedee
 Comments
Text
Mediating ItemRenderers

ListBase, what it is and is not.

The ListBase classes are containers. In their simplest form, they mimic a typical OS list. In this capacity they work fairly well, and I see very little reason to mediate ItemRenderers. But they can be used for things far outside the scope of a typical list. This other use, I will refer to as the “Optimised Continuum Container”. Cool name eh? :)

Continuum Containers.

A “Continuum Container” is any container that presents a collection (the continuum) along an axis (1). VBox and HBox are prime examples. When the continuum get’s long, we need a scrolling mechanism to present the continuum to the user (2).

When the continuum gets very long, we need to ‘Optimise’ the container such that it only instantiates enough children to represent what’s on screen (3). That’s what the ListBase classes do.

A UX decision

We decided that we wanted to present a list of items to the user in such a way that common goals (actions upon the items) were easy to find and use. Lets say its an employee list. Here’s a typical implementation of a list, with actions associated:

Maybe not too typical, this obviously has some design challenges. Common actions for a list item should be readily locatable. One way of doing this is shown above, you keep the actions still (motionless, in one obvious place), and you select the item upon which to act.

When your list window gets large, as ours often do, the travel time with the mouse to the action items becomes frustrating and can cause disorientation. So what we do is (and you’ve seen this many times before) is to group the actions with the list item:

Not a typical ListItem

So suddenly we don’t have typical list items. Each list item has more than one “concern” now:

  • Present the name
  • Present the state of “in/out”
  • Accept input to change “in/out” state
  • Accept input to launch the editor
  • Accept input to edit the item
  • Accept input to launch an email window

It get’s even more complicated when there are modelled conditions that lie outside the VO, for example, if the user does not have permission to send emails from the application, we don’t want to show the email button.

I personally believe that these concerns should be seperate. When I first saw an example of a view-mediator tuple for a single button, I thought “What horrendous overkill”. Now I’ve been Robotlegging it for a while, I can’t imagine a life less granular, and I always try to get my view/mediator “concern count” near to 1.

If you don’t agree with that last paragraph, then you won’t need to mediate ItemRenderers.

The view for my list item in that example includes several child views (and mediators) for each button. This is so clean and simple to refactor, and to read, that I would not have it any other way (pragmatically speaking).

Mediating ItemRenderers

ItemRenderers and ItemEditors lead a fragile existence and are not straight-forward to mediate. This does not mean you can’t mediate them, it means you must know your enemy.

ItemRenderers are re-used.

So when an item goes off the list, it’s renderer does not get destroyed, instead the ‘data’ property is set to a new item and the renderer is moved into place on the list.

This means that you can’t simply rely on instantiation and the event bus to observe when you need to mediate your view. You need to also watch the data property. That’s not so hard now is it?

Typically when you mediate, you establish state on instantiation (if necessary) and modify state as changes come off the event bus (and binding). This means that you establish an accurate reflection of state by knowing the previous “reflection of state” was correct

That’s what makes ItemRenderers a little harder, you need to reset state more often, and there are more gotchas.

For example, when we save an edit on a list item, we tell the Renderer (not the editor) to switch to a busy “spinny circle” state. If the item goes off screen, the Renderer get’s reused for something else, and we must reset it’s state such that it doesn’t look busy. If the item comes back on screen while still saving to the server (hello New Zealand ping times), then we need to reset it’s state to busy.

I’ll try to write a follow up article on best practices for resetting ItemRenderer state.

ItemEditors stand in for renderers.

When an item is editable and the user begins an edit, the ItemRenderer is hidden, and a new ItemEditor is instantiated. This means that whatever mediation you use for the renderer, may well need to be duplicated for the editor. I keep these concerns seperate and look for common code via common refactoring methods (extract*).

Stick with the basics.

Despite all this, we do have a simple set of rules we always follow, no matter the renderer. I’ll spell them out here, and in my next article I’ll show some working code.

  • Use the VO dependency provided by the list (.data property)
  • OnItemEditBegin and OnItemEditEnd are handled at the parent (list) mediator.
  • When an edit begins (OnItemEditBegin), our list mediator asks the model for an editable VO and provides that to the list in place of the original VO.
  • When an edit ends (OnItemEditEnd) the list mediator issues a command to save the modified VO. This keeps us canonical with the server/services.

05:26 pm, jonathan-visfleet
 Comments
Text
Debian Squeeze Kernel for Ubuntu 9.04 XenServer DomU

Squeeze, the testing version of Debian ships with a more recent kernel which works well on a XenServer 5.5 guest. The version is 2.6.30-2-686-bigmem.

I am evaluating whether this is a stable kernel for use under Ubuntu Jaunty 9.04. Up till now the best kernel has been 2.6.26-2-xen-686 from Debian Lenny. However, this older kernel has known issues which I am keen to avoid.

The newer Squeeze kernel down be downloaded from a Debian mirror, in my case the NZ mirror:

http://ftp.nz.debian.org/debian/pool/main/l/linux-2.6/linux-image-2.6.30-2-686-bigmem_2.6.30-8squeeze1_i386.deb

Installing was as simple as:

dpkg -i linux-image-2.6.30-2-686-bigmem_2.6.30-8squeeze1_i386.deb

A couple more changes were required. In XenCenter, the guest’s Properties => Startup Options => OS Boot Parameters need to be changed to use the correct console device:

console=hvc0

In addition, the guest VM needs to have a new file created to run a getty on hvc0, so that the Console tab works in XenCenter. As root, create the file /etc/event.d/hvc0:

# hvc0 - getty
#
# This service maintains a getty on hvc0 from the point the system is
# started until it is shut down again.

start on stopped rc2
start on stopped rc3
start on stopped rc4
start on stopped rc5

stop on runlevel 0
stop on runlevel 1
stop on runlevel 6

respawn
exec /sbin/getty 38400 hvc0

Then reboot.


01:14 pm, jonathan-visfleet
 Comments
Text
Citrix XenServer: Debian APT Repo Public Key

Citrix have a APT repository which provides a para-virtual kernel and some guest tools for linux guests on XenServer.

The repo looks like this in /etc/apt/sources.list:

deb     http://updates.vmd.citrix.com/XenServer/5.5.0/debian/ lenny main
deb-src http://updates.vmd.citrix.com/XenServer/5.5.0/debian/ lenny main

On a default deploy, the public key for the repo is obviously not added locally, which ends up throwing this kind of error during apt-get update:

W: GPG error: http://updates.vmd.citrix.com lenny Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 841D6D8DFE3F8BB2
W: You may want to run apt-get update to correct these problems

The fix is to add the Citrix public key:

wget -q http://updates.vmd.citrix.com/XenServer/5.5.0/GPG-KEY -O- | apt-key add -

Which should result in a satisfying “OK” message on the console.


04:42 pm, jonathan-visfleet
 Comments
Text
Ubuntu 9.04 + PSP + Firmware Updates on HP DL380 G5

PSP Install

We prefer to use Ubuntu on our production servers for all kinds of reasons. With this choice however usually comes a lack of vendor support (because how can a Linux distro be enterprise if you don’t pay money for it?).

The ProLiant Support Pack (PSP) provides a whole bunch of great software which helps with server management. I especially needed to update the firmware on our E200 RAID controller and SAS drives.

HP have recently added PSP support for Ubuntu Jaunty 9.04 (and Debian Lenny 5.0) for many of their server models, so I downloaded the current PSP for our servers from here

I ignored the instructions to use apt-cdrom, and instead mounted the ISO on the target machine with:

mount -o loop HP_ProLiant_Value_Add_Software-8.25-19-12.iso /mnt/

then added the repo (temporarily) to /etc/apt/sources.list:

deb file:/mnt jaunty/8.25 non-free

then updated and installed all the packages:

apt-get update
apt-get install lib32gcc1
apt-get install hp-health
apt-get install hp-snmp-agents
apt-get install hpsmh
apt-get install hp-smh-templates
apt-get install hpacucli
apt-get install cpqacuxe

At this point the /etc/apt/sources.list entry can be removed.

It is then necessary to run the snmp setup tool to make things report:

/sbin/hpsnmpconfig
[ answers go here ]
/etc/init.d/hp-snmp-agents restart

I just supplied enough answers to get things working locally.

To use the web based version of the array configuration utility, the daemon needs to be started on the host:

/usr/sbin/cpqacuxe -R

I also added this into /etc/rc.local to make sure it runs at boot:

/usr/sbin/cpqacuxe -R > /dev/null

The HP System Management Homepage (SMH) and Array Configuration Utility can be then accessed at https://[host]:2381

Firmware Updates

The online firmware update tools from HP are good. A bit tricky to get going though.

I got the updated firmware and disk firmwares for the E200 smart array controller from here

The link above is for 64 bit RHEL 5, but they will execute fine on 64 bit Ubuntu 9.04 after a few tweaks.

The firmware for the controller was under Firmware - Storage Controller with a description of Firmware CD Supplemental Update / Online ROM Flash Component for Linux - Smart Array E200 and E200i

At the same time, I used the SMH to find out the Model Number of each of the installed drives. Then found the new firmware downloads for those drives on the same downloads page.

To apply the firmware updates under Ubuntu, you need to do some hackery as outlined here. To repeat his instructions:

wget http://mediakey.dk/~cc/files/compat-libstdc++-296-2.96-138.i386.rpm
aptitude install rpm
rpm2cpio compat-libstdc++-296-2.96-138.i386.rpm | cpio -idmv
export LD_LIBRARY_PATH=/root/usr/lib/:$LD_LIBRARY_PATH
ldconfig

Then executed the downloaded controller firmware update file (in my case):

/bin/bash ./CP011557.scexe

The program did throw some errors, but I just ignored them as they didn’t cause any issues:

./CP011557.scexe: 344: pushd: not found
./CP011557.scexe: 344: popd: not found

Using iLO, I did a cold boot as instructed, after applying the controller firmware update. As the server booted with the new controller firmware revision, the RAID BIOS threw a couple of quick messages to indicate that the firmware on some of the drives was now out of date. Good, because that is the next thing I updated.

At the next login I applied the two firmware updates for the two types of SAS drive that are installed on that server:

export LD_LIBRARY_PATH=/root/usr/lib/:$LD_LIBRARY_PATH
/bin/bash ./CP011615.scexe
/bin/bash ./CP011617.scexe

The updates prompted for all the drives that needed updating. After applying both I did another cold boot (thanks iLO). Job done.


08:42 am, squeedee
 Comments
Text
Robotlegs. What I'm falling in love with.

Background

I just thought I’d comment on my latest endeavor at Visfleet. I’ve been a little worried about my cobbled together framework for our Flex codebase. It was designed and added too from the day we started with Flex 2 and hasn’t had a proper review since. It works, and we have workable code, but I find that the developers here have the same trouble using it over and over again. So I identified my biggest ongoing concerns:

Hard to Test Code

Sure some unit tests could be attached, but I use registries and locators for dependency injection. There are some really nice DI frameworks around now, it’s time to use one.

Sloppy Inversion of Control

IOC is sloppy due to many levels of inheritance. I use inversion of control by means of placeholder virtual methods, which after one level of inheritance still leaves us with a “call super” anti-pattern. Or with the need to add more virtual methods. I’d rather just not depend on inheritcance so often.

Namespace polution

There’s no convention in my current framework that makes enough sense when it comes to naming and positioning classes. I see Rails apps that do this so well and I get envious. Can haz conventions?

Service and Model mixed

Just don’t know what I was thinking. In the days of the mostly read only API (iVistra’s focus on visualization) I could get away with a “ListLoader” class that maintained a canonical representation of server side data using a limited CRUD command set and RESTful view of the data. RESTful is a great place to start with any service, but I think you’re a fool if you try to ‘Resourcify’ everything. It’s definitely not pragmattic, and it’s often not practical either.

[robotlegs]

This is robotlegs. Currently the documentation is a little confused about what Robotlegs is (or I find it confiusing). But here’s what I’ve gleaned from Shaun Smith (inventor) and Joel Hooks (major contributor):

[robotlegs] the DI automation framework

Robotlegs is a framework for the automation of Dependency Injection. It should be possible to plug any DI framework into it. At the moment, SwiftSuspenders is the only one successfully and completely “adapted”.

To quote Shaun:

Robotlegs aims (and does not succeed 100%.. yet) to be a set of tools for automating DI and nothing more. It’s not a DI framework itself.

It provides:

  • A CommandMap - for instantiating, injecting and executing Commands triggered by an EventDispatcher.
  • A MediatorMap - for instantiating, injecting and registering Mediators as view components arrive on stage in a given context
  • A ViewMap - for injecting directly into view components as they arrive on stage in a given context

SwiftSuspenders

SwiftSuspenders is a simple and fast DI framework. It uses very little metadata but I find it very effective. Just try it, even if you don’t use RL, it’s so simple and effective.

[robotlegs] MVCS

Let’s call this RL-MVCS for the purpose of this discussion.

This is a reference implementation MVC framework written using Robotlegs. This is where most of the confusion arises.

When you look at Robotlegs demos, it’s usually RL-MVCS. When you look at Robotlegs discussions, it’s often about RL-MVCS. When you read the best practices documentation, it is entirely about RL-MVCS.

That said. I really like this implementation. The only thing I’d like to see made simpler is the idea of “sub contexts”, which I use for separating components and for separating modules, where a module is a largely separate “application domain”.

What [robotlegs] Addresses.

Returning to my concerns for my current framework, SwiftSuspenders adresses my sloppy IOC and DI issues directly. [robotlegs] the DI framework is even better though because:

  • I get the ability to switch to a different DI framework (although I might have to write the adapter).
  • I get an easily introduced mechanism for adding DI to my existing MVC implementation.
  • I get documentation, open discussion and an open convention.

The conventions would help me improve my namespace pollution issues, but I’d still need to do a lot of work and document it myself. Ditto for the service/model coupling I have.

So this is why I love RL-MVCS, I get all of the RL-DI improvements plus:

  • An MVC implementation that has examples, open convention, and open discussion.
  • A thoroughly well thought through best practice guide.
  • A framework based entirely on OO best practices. It’s actually quite hard to cut corners with RL-MVCS.
  • Conventions that pry my classes apart until they are testable.
  • Conventions that let me readily reduce my long inheritance chains through DI.
  • Nice examples of working projects with tests in place (but not compiled into the final product, Yay!)

Also, I’ve edified myself on RL-MVCS by picking one system component of our application and only implementing it there. So right now, I have my own application mostly untouched, with just one little corner of it’s world implemented in RL to prove its value. It’s no mean feat for a MVC style framework to be able to work so readily inside another.


08:58 am, visfleet
 Comments
Text
Flex State Machine Release 0.1

http://github.com/visfleet/FlexStateMachine

I’ll call this the first release :)

Flex state machine is my attempt at getting a domain specific language (DSL) for state machines into Flex.

It’s missing a vital ingredient (to my mind), which is the ability to mix events and ‘cans’ (State events, not the Flex observer pattern) into another class instance.

The kludgy:

controller.machine.start()

should be replaceable with

controller.start()

I just need to take a closer look at the EventDispatcher mixin mechanism and see if I can use that to implement a ‘method missing’ solution that will at least work with controller/model/facade classes marked as dynamic.

Despite this annoyance, I love this class and it works beautifully in our production code. Please give it a whirl and feedback/fork away.