Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: Handler classes for mediators  (Read 10388 times)
sasuke
Full Member
***
Posts: 29


View Profile Email
« on: November 11, 2009, 11:28:29 »

Hi all.

When creating mediators for complicated views, the handleNotification method quickly gets out of hand and becomes overly complex when dealing with a bunch of notifications. Would it be a good idea to introduce the concept of handler classes for mediators which lead to even more cohesion [i.e. the handler responsible for handling notifications as opposed to Mediators]. Something along the lines of:

:
public interface IHandler
{
        function handle(notification:INotification);
}

public class NotificationHandler implements IHandler
{
protected var viewComponent:Object;

public function NotificationHandler(viewComponent:Object)
{
super();
this.viewComponent = viewComponent;
}

public function handle(notification:INotification):void
{
// Do nothing, just a base class for other handler classes
}
}

public class BaseMediator extends Mediator
{
protected var handler:IHandler;

override public function handleNotification(notification:INotification):void
{
// If the control reaches here means that the implementing
// class has not overidden the handleNotification funciton.
// Try to handle the notification if the IHandler is set
// otherwise just do a NO-OP
if(handler)
{
handler.handle(notification);
}
}
}

public class MyModuleHandler extends NotificationHandler
{
override public function handle(notification:INotification):void
{
// do something interesting here with the notifications
}
}

public class MyMediator extends BaseMediator
{
public static const FIRST_NOTIFICATION:String = 'FIRST_NOTIFICATION';

public static const SECOND_NOTIFICATION:String = 'SECOND_NOTIFICATION';

public function MyMediator(mediatorName:String=null, viewComponent:Object=null)
{
super(mediatorName, viewComponent);
}

override public function onRegister():void
{
handler = new MyModuleHandler(viewComponent);
}

override public function listNotificationInterests():Array
{
return [
FIRST_NOTIFICATION,
SECOND_NOTIFICATION
];
}
}

What do you guys think? If not this, then what else can be done to remedy the above scenario?

TIA,
sasuke
Logged
Jason MacDonald
Sr. Member
****
Posts: 243


View Profile Email
« Reply #1 on: November 12, 2009, 08:24:48 »

If your mediators are getting "out of hand" then you are putting too much logic into your mediators. You shouldn't be putting more than simple "get" and "set" calls in your mediators. Anything more complex should go in a command. It sounds like you are over extending the mediator to pefrom tasks it is not meant to.

As Cliff has stated before, the mediator handleNotification method is constructed in such a way that it acts as a kind of snaity code check. If you find it's getting unwieldy, then it's a sign you are trying to do too much and need to refactor.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #2 on: November 12, 2009, 09:22:13 »

For the most part, as Jason mentioned, to many interests is usually a sign of an overworked mediator and the answer is usually to cleave it in twain. Make two (or more) mediators that handle different sub-assemblies of this (clearly mammoth) view component.

But there are some places where a mediator class hierarchy as you've described can be helpful. If you have several cross-cutting concerns, you can leverage this approach successfully.

Such as in MultiCore apps using pipes, the JunctionMediator (part of the pipes utility) handles notifications common to all pipe aware modules (accepting input and output pipes) and the subclass handles all the specific stuff to that core.

In the PipeWorks application it actually goes to three levels of hierarchy.

JunctionMediator is extended by LoggingJunctionMediator which adds the ability for every core send messages to the logger. Then the ShellJunctionMediator and the PrattlerJunctionMediator both extend LoggingJunctionMediator to add the specific notification handling for the Shell and Prattler modules.

:
       
    public class PrattlerJunctionMediator extends LoggingJunctionMediator
    {
        public static const NAME:String = 'PrattlerJunctionMediator';

        /**
         * Constructor.
         * <P>
         * Creates and registers its own STDIN pipe
         * and adds this instance as a listener,
         * because the logger uses a TeeMerge and
         * new inputs are added to it rather than
         * as separate pipes registered with the
         * Junction.</P>
         */         
        public function PrattlerJunctionMediator( )
        {
            super( NAME, new Junction() );
           
        }

       /**
         * List Notification Interests.
         * <P>
         * Adds subclass interests to those of the JunctionMediator.</P>
         */
        override public function listNotificationInterests():Array
        {
            var interests:Array = super.listNotificationInterests();
            interests.push(ApplicationFacade.EXPORT_FEED_WINDOW);
            return interests;
        }

        /**
         * Handle Junction related Notifications for the PrattlerModule.
         * <P>
         * For the Prattler, this consists of exporting the
         * FeedWindow in a PipeMessage to STDSHELL, as well as the
         * ordinary JunctionMediator duties of accepting input
         * and output pipes from the Shell.</P>
         * <P>
         * Also send messages to the logger (via the direct superclass
         * LoggingJunctionMediator.</P>
         */       
        override public function handleNotification( note:INotification ):void
        {
           
            switch( note.getName() )
            {
                // Send the FeedWindow Component
                case ApplicationFacade.EXPORT_FEED_WINDOW:
                    var prattlerWindowMessage:UIQueryMessage = new UIQueryMessage( UIQueryMessage.SET, PrattlerModule.FEED_WINDOW_UI, UIComponent(note.getBody()) );
                    junction.sendMessage( PipeAwareModule.STDSHELL, prattlerWindowMessage );
                    break;
               
                // And let super handle the rest (ACCEPT_OUTPUT_PIPE, ACCEPT_INPUT_PIPE, SEND_TO_LOG)                               
                default:
                    super.handleNotification(note);
                   
            }
        }
    }
}


-=Cliff>
Logged
Jason MacDonald
Sr. Member
****
Posts: 243


View Profile Email
« Reply #3 on: November 12, 2009, 10:16:00 »

I may have misunderstood the issue. I thought the issue was he had overly complex handlers (ie: trying to do way too mcuh per handler), not too many handlers in general.
Logged
sasuke
Full Member
***
Posts: 29


View Profile Email
« Reply #4 on: November 16, 2009, 11:01:19 »

Having read this thread http://forums.puremvc.org/index.php?topic=1524.0 I realized that I was trying to solve the wrong problem here. Rather than going by the SRP and striving for separation of concerns, I was just shifting the burden from mediators to handlers.

Thanks for the replies Cliff & others. :)

-sasuke
Logged
Pages: [1]
Print