The primary focal point for aMVC is the anaonymous controller. this class is in fact the motivator for the creation of the aMVC architecture. The basic underlying motivation was a centralized point of control for messaging that was not dependent on global constants, or a priori knowledge of events or functional commands.
This is one of the major drawbacks of architectures like Cairngorm (other than class overload). In Cairngorm, the FrontController class is a central mechanism in  the application that links events to responders (Commands). In a shared production environment, this requires an integration step in development work to capture all communication in a central place. In the original formulation there was also a conflict introduced by using Modular development, where there was conflict between the central application controller, and those built to support Module functionality. This conflict was resolved, thanks to work by groups such as Universal Mind, by allowing the application controller to register the FrontControllers of individual modules

In the aMVC formulation, the Controller class acts as a message gateway. Events, defined as constants elsewhere in application, are registered with the controller anonymously via the use of a Dictionary. As part of this registration (via the EventRegistrationDTO), a responder is passed and assigned via the Dictionary to this event. This initial registration and that of other interested parties are captured in the same Dictionary entry. When an event of this type is dispatched, all interested parties are notified of the event via the registered responder.

The controller neither knows nor cares who is doing the registration, who dispatched the event (is is dispatched directly on the controller, which is a Singleton), or who will handle (or initiate) actions that correspond to this event.  As outlined in the function relationship diagram, a typical flow would have a Command instance registering interest with the Controller for an event that is dispatched by a view component that responds to user interaction. This is not the only scenario e.g. view registers response handler from an event dispatch elsewhere in the application.

The framework relies on a single event Class the DataTransportEvent that can be utilized to pass any data or none. These classes are outlined here:

Controller.as

/*
 * Controller.as
 *
 * Copyleft(c) 2010 Darin Kohles.  All Rights Reserved.
 *                        www.dkohles.com
 *
 * Date: April 10, 2010
 * Author: darin@dkohles.com
 *
 */
package com.dkohles.core.control
{
import com.dkohles.core.base.SingletonBase;
import com.dkohles.core.events.DataTransportEvent;
import com.dkohles.core.events.EventRegistrationDTO;

import flash.utils.Dictionary;

import mx.rpc.IResponder;

public class Controller extends SingletonBase
{
private var responseDirectory:Dictionary;
private var eventDirectory:Dictionary;

protected var svc:M3RemoteServices;
protected var model:M3Model;

public function M3Controller()
{
super();
}

/**
* Add a responder to an event type. Used by module classes to register interest in
* external events.
* @param reg pass through object containing event type information and the responder for the event.
*
*/
public function registerHandler( reg:EventRegistrationDTO ):void
{
if( eventDirectory == null ){
eventDirectory = new Dictionary();
}

if( eventDirectory[ reg.eventName ] == null ){
eventDirectory[ reg.eventName ] = true;
addEventListener( reg.eventName, handleEvent );
}

if( responseDirectory == null ){
responseDirectory = new Dictionary();
}

if( responseDirectory[ reg.eventName ] == null ){
responseDirectory[ reg.eventName ] = new Array();
}

( responseDirectory[ reg.eventName ] as Array).push( reg.responder );
}

/**
* Remove notification interest by responder. Used to decouple component from external
* events that had been previously been tracked. Also clean up the controller dictionary
* if no other parties are interested.
*
* @param reg pass through object containing event type information and the responder for the event.
*
*/
public function deRegisterHandler( reg:EventRegistrationDTO ):void
{
var index:int = (responseDirectory[ reg.eventName ] as Array).indexOf( reg.responder );
if(index >=0 ) (responseDirectory[ reg.eventName ] as Array).splice( index, 1 );

if( (responseDirectory[ reg.eventName ] as Array).length == 0)
{
responseDirectory[ reg.eventName ] = null;
this.removeEventListener( reg.eventName, handleEvent );
}
}

/**
* Pass the event directly to the responder(s) directly.
*
* @param evt event fired by normal application flow or user gesture
*
*/
private function handleEvent( evt:DataTransportEvent ):void
{
var respArray:Array = responseDirectory[ evt.type ];
if( respArray != null && respArray.length > 0 ){
for(var i:int = 0 ; i < respArray.length ; i++ ){
if( (respArray[i] as IResponder).result != null ){
(respArray[i] as IResponder).result( evt.data );
}
}
}
}

/**
* Retrieve responders for a given event.
*
* @param evt event type of interest.
*
*/
private function getResponders( type:String ):Array
{
var respArray:Array;
if( eventDirectory[ type ] ){
respArray = responseDirectory[ type ];
}
}
}
}

EventRegistrationDTO.as

/*
* EventRegistrationDTO.as
*
* Copyleft(c) 2010 Darin Kohles.  All Rights Reserved.
*                        www.dkohles.com
 *
* Date: April 10, 2010
* Author: darin@dkohles.com
*
*/
package com.dkohles.core.events
{
import mx.rpc.IResponder;
import mx.rpc.Responder;

public class EventRegistrationDTO
{
public var responder:Responder;
public var eventName:String;

public function EventRegistrationDTO( evt:String, resp:Responder )
{
this.eventName = evt;
this.responder = resp;
}

}
}

DataTransportEvent.as

/*
* DataTransportEvent.as
*
* Copyleft(c) 2010 Darin Kohles.  All Rights Reserved.
*                        www.dkohles.com
 *
* Date: April 10, 2010
* Author: darin@dkohles.com
*
*/
package com.dkohles.core.events
{
import flash.events.Event;

public class DataTransportEvent extends Event
{
public var data:*;

public function DataTransportEvent(type:String, data:*, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);

this.data = data;
}

}
}

The motivation behind the Anonymous MVC Framework (aMVC), was to separate the aspects of frameworks like Cairngorm and Pure MVC that simplify and empower application development, while avoiding the pitfalls of “centralization” that come with these implementations. The “Anonymous” portion of this framework is the use of a centralized control mechanism that simply acts as a traffic monitor for user and application initiated events.

The basic concept here is that “players” will register their interest in various events via the central controller. “Players” can be individual view components, or more commonly a command class representing a portion of the view (or it’s entirety). Part of the registration process is the pass-through of a callback function. It is in this callback that the actual activity triggered by the event is done. The callback can act within the command class, via a delegate, or directly within a view.

The framework advocates the use of a central application model (singleton), but does not preclude multiple models representing distinct portions of the application. This same holds true of all aspects of the framework, as each portion, instantiated as a singleton, is based on the qualified class. If you want to use the centralized version, call the base class, if you want to divide responsibility, simple extend the base for local use (as in Modules etc..).  The overall structure is as follows:

Framework Overview

Because of the anonymous nature of this framework, the components can be wired together with many variations:

In future posts I will elucidate further the components of this framework.