ARP: Controller vs. Glorified Hashmap

Good discussion over my blog that spilled to email with Grant Davies. He did a coup de grace whilst I drank watered down coffee on my ARP mods. He called my modified ARP Controller a glorified hashmap, and he’s right.

The Controller in ARP responds to events made from View’s, and runs Commands when those events happen. You click the Submit button, it dispatches the click event. The Controller is listening for the click event, and runs the Login command. Your atypical MVC Controller; listen to events, trigger code to respond to those events.

I’m faced with a challenge which I’ll probably solve while writing this. Since my changes, the Controller is no longer a controller in the traditional sense. It merely holds command classes in a hashmap (ActionScript Object), and allows you to run them (instantiate the class, optionally passing parameters). That is not a Controller.

To reiterate the reason I did this to give some history and context, I felt that when writing dispatchEvent in my View’s, it shouldn’t imply anything. To me, event names are spur of the moment, just like naming variables; “What should I call this that’ll make sense, fall more to the verbose side vs. the brief side, and overall make sense?” In ARP, however, this choice carries with it the addition of knowing this event may eventually end up being mapped to calling a Command in the Controller. I didn’t like this, at least for those high level View’s that would be considered emitting system events. Granted, you wouldn’t have to worry about a Button’s click event triggering a command, but your Login component could trigger a command by its click event.

Peter Hall and I had Aral note our distress, and he in turn suggested we use handleEvent which would allow us to intercept any events and do the mapping ourselves if we so chose. Since handleEvent is called before the actual event on an event listener using EventDispatcher in Flash/Flex, it’s a nice, low-level way to get more control of your events.

At this point, I may have to re-examine that as an option.

Typically what I’ve been doing is making an Application class; whether extending my ApplicationTemplate, or Flex’ Application.mxml. This holds all initial logic to create the main GUI’s, who in turn holds all other View creation/destroying, and manages listening to events and running commands; in effect, it’s a Controller and a View in 1; not so strange in Flash. Many purists do not like doing this since a Controller should be a controller and just a controller, and I understand perfectly why. ARP being lightweight enough allows me to bend the rules to my liking.

However, I don’t think I can bend word definitions however; Controller is no longer such, and without multiple inheritance, I cannot have mx.core.View & Controller become one and the same without using an mix-in which most people, except me, hate.

…ok, that didn’t work, writing it out didn’t solve it. Perhaps if Controller extended mx.core.View instead of Object, I could use it as my base View/Controller class since most of my apps are Form based anyway, this would work out well. Back to the lab.

Community input, rocks!

5 Replies to “ARP: Controller vs. Glorified Hashmap”

  1. hi jesse,

    i took a very alike approach that you handle the whole app with one Application class (which contains many views), but i do have many view-controller pairs (usaually i see those pair as some kind of windows form) although they may be combined in one class (in flash).

    I don’t think it’s wrong to ‘bend’ the approach since framework are there to help us get the things done, as long as it works. (personaly i have a very-heavily-bent-ARP-alike framework, with Application and Form template class doing all the underlying stuff, but what matters is that framework helped me to gain productivity by 2-5 times :-)

  2. Thanks mate… I guess I’m so excited I’ve finally reached a point where I enjoy working with my code; I don’t hate it. To me, that’s a pinnacle I’ve been wanting to reach for years now. I, frankly, don’t know what else to do at this piont, but what I’ve been doing, and that’s keep improving (or making perceived improvements) on my current workflow.

  3. Jesse,

    oops, didn’t mean to insult your controller :)

    Why don’t you make a controller tied to the business you are trying to perform and have a map between and event string and a command. The reason I don’t like my view’s directly firing a command is sometimes my views get used over different applications, so the command that gets fired based on an event may change.

    You could even throw up a controller on the fly when you create the particular view

    controller = controllerFactory.getGetController();
    controller.addCommand(‘login’, loginCommand);
    controller.addCommand(‘changePassword’, changePasswordCommand);
    view.addEventListener(controller);

    I tend to have a few small controllers rather than one huge one. Plus in a real application most views don’t exist at compile time so you need a way to dynamically map events and commands.

    One thing I’m doing and I’m still not sure its ‘honest’ is allowing my command to publish business events not ‘click’ but events like ‘UserRolesLoaded’;

    For example: once the user has logged into my application I do a lot of preloading of data for performance, I want the user to take 1 hit after login to intialize the application. I have to load a lot of stuff and for example, I load all the possible roles a user can be assigned to (its a role based authorization administration system). So after they login my application dispatches a ‘getAllRoles’ event which is mapped to the GetAllRoles command, once this command has finished it dispatches a ‘UserRolesLoaded’ event. This issue I have here is I don’t really want my application as a ‘listener’ of the command, I actually want some ‘system events’ to be global so instead of my command
    displatching the event my master controller does

    e.g

    SystemController.getInstance.dispatchEvent({type:’UserRolesLoaded’});

    So now my applcation can do this :
    SystemController.getInstance.addEventListener(‘UserRolesLoaded’, Delegetate.create(this, onRolesLoaded);

    I hope this is clear but what I think I have is something loosely coupled but also not too heavy. The only issue I have now is my commands are sometimes invoked from a view and sometimes due to a system event so inside my command I have to check if viewref is null before doing anything as sometimes there may not be a viewRef.

    I think I’ve got basically what you did with your ARP extensions I just didn’t find the view being tightly coupled to a command like your extensions would work for the type of projects I do where I do have a lot of view re-use but commands change often.

  4. Please could someone help me out? I’ve gone done the road of loading external swfs to keep things as modular as possible, but I now have no idea how to register the swf with the Application. There seems to be a lot of high level discussion on the ARP mailing list, but no one is actually giving concrete examples.

    Many thanks.

Comments are closed.