One class controller instead of multiple command

Oleg Borisov's Avatar

Oleg Borisov

18 May, 2011 07:06 PM

My question is simple: Is it possible to combine in one class-controller instead of multiple command?

Let me explain

I have the general application (tens of services, loadable modules and other). And I have the hundreds of commands. And I need to accumulate these commands on several classes (divided by the business logic).

For example:

In my Context I describe my Class-Controller:

injector.mapSingleton( WebServiceController,'WebServiceController' );

After that I start the my first View/Mediator (loading page) and in the Mediator I initialize my controller:

[Inject (name='WebServiceController')] public var wC : WebServiceController;

override public function onRegister() : void {

// init authorization service and start initialization activity in system
wC.Init();
...

In Controller->Init() :

public function Init() : void {

eventDispatcher.addEventListener(

UIStateEvents.AUTHORIZATION_INIT_OK, AuthorizatonInitOkHandler
); }

What can I get in this variant?

1) I accumulate all my command for web service in one place
2) I don’t need to write for every command : create new command class, don’t forget to map this command in context...
3) I have simple navigation in my source code : list of controllers without commands-commands-commands files

General activity: split the business logic in list of controllers, describe commands as functions in these classes and map to listener list of events.

Could you please criticize this variant and point out possible problems?

  1. 1 Posted by Stray on 18 May, 2011 07:35 PM

    Stray's Avatar

    Hi Oleg,

    the Commands vs Controllers debate is a long running one.

    Personally I love the Command pattern - I find it to be easier to test, easier to refactor and easier to find what I need at a later date.

    The weak points of the Command pattern are:

    1) Logic is distributed, this means that if your Commands aren't very well named then it can be hard to find what you are looking for.
    2) You can end up with repeated-code in some Commands.

    I think 1) is solved by naming Commands well and 2) is solved using composition and helper classes in your Comands (even a class that just does one logic step can be useful as far as I am concerned).

    But - in addition, I'd just suggest reading up on Controllers vs Commands. Google it. The debates rage :)

    A simple way to achieve the Controller approach in Robotlegs is to use an Actor as a 'Controller Mediator'. This Actor (which would be created as a Singleton using the injector) would listen for events on the eventMap and then call functions on the Controller. Personally I don't like Controllers, so I wouldn't use this approach, but it certainly works.

    But you should really consider helper classes for your commands first...

    Stray

  2. Support Staff 2 Posted by Till Schneidere... on 18 May, 2011 07:37 PM

    Till Schneidereit's Avatar

    I tend to see the list of command classes as a great way to get a
    quick overview of a module's functionality. The list, if done
    properly, contains all "gestures" the module can perform. "Module",
    though, can be as fine-grained as you like: It can be the entire
    application, a (Flex-)module, or specific area of functionality in an
    application as in your webservice example. In fact, I'd recommend
    using packages to organize your source in much the same way as you
    propose using fat controller classes.

    That being said, your approach has a couple of down-sides:
    - Instead of simply informing the application about something that
    happened in the view without caring about how, or even if, the
    application is going to react to it, it tells the controller what to
    do. That causes a lot of coupling you don't get when using the
    CommandMap
    - The controller being a singleton means that you can never have
    multiple "commands" running side-by-side. That only gets problematic
    when using asynchronous commands, of course, so it might not be a
    problem for you at all

    Here's how I go about organizing an application's wiring:
    - implement each area of functionality in its own sub-package
    - in each of these sub-packages, have a command that contains
    instructions for how to configure and wire that area: Mapping commands
    and mediators, setting up models and services, etc.
    - when your application uses the functionality, include this setup
    command in your startup sequence

    There's been lots of discussion about the "right" structure in the
    support forum. One good such discussion is:
    http://knowledge.robotlegs.org/discussions/questions/222-package-structure
    but I recommend searching through the discussions and seeing if
    there's something you like.

    On another note, is there a specific reason why you've named your
    singleton mapping? It looks to me like you're simply repeating the
    class name. Named injections are only ever required if you want to
    inject multiple unique values of one type. For example, people use
    them to map different strings for configuration purposes. If that's
    not what you're doing, just get rid of the second parameter in your
    mapping and the "name" parameter in your [Inject] tag.

  3. 3 Posted by Oleg Borisov on 18 May, 2011 08:19 PM

    Oleg Borisov's Avatar

    Thanks all...

    Stray,

    I need to understand, should I use my idea (class-controller + mapping commands as functions in this controller) in Robotlegs environment and what potential problem will I have...

    My opinion, I don't broke the general idea of Robotleg. I create the up-domain for group of commands and restructure my code over small part of big-controllers.

    And I need to select the correct/flexible/supportable variant for the future. Now I have to create new command - generate new file + additional code (inject of event class, inject of target model/service, rewrite execute function)...

    If I use the one controller for group of activity, I can create the list of functions + map this functions to events. It's all...

    For example:

    public class AuthorizationInitOkCommand extends Command {

    [Inject]
    public var e : UIStateEvents;       
    [Inject (name='IPluginDataService')]
    public var pluginService : IPluginDataService;
    ...
    override public function execute():void {
    ...
    

    and for another authorization command, and another...

    And I can change it: one controller class, and 10-20-... functions.
    I think, I don't corrupt the general idea of framework + I will use all possibilities, include general event mechanism and other...

  4. 4 Posted by Stray on 18 May, 2011 08:28 PM

    Stray's Avatar

    Writing code is less than 10% of your effort.

    If you think making a Command is 'work' then you need a better IDE, not a different architecture :)

  5. 5 Posted by Oleg Borisov on 18 May, 2011 08:34 PM

    Oleg Borisov's Avatar

    tschneidereit,

    About "named singleton". I should use it for resolve the potential 'cicle' problem.

    For example, I have 2 classes:

    injector.mapSingleton( Class1);
    injector.mapSingleton( Class2);

    And I use in the Class1 injection to Class2, and in Class2 I can have the Injection to Class1. If I use no-name specification, I have the following collision:

    Robot calls the Class1 initialization, has found the injection to Class2, try to create it, found the injection to Class1, ... and I have the recursion error.

    About modules/commands and my general question.

    Me inconvenient to keep a large number of files, classes, each of which can carry a tiny operation. At the same time - I need to describe it and generate a large piece of code to create this class, describe the links to the common commands for this group of models and services, etc.

    I realize this is more convenient in the form of Controller-class, which collect a piece of business logic in one place.

    And I try to understand - is it correct in range of Robotlegs or not.

    My mediators send events, mapped Controller gets this information and executes the functions-commands and manipulates to models and services. If you see the class diagramm, I will create the block of controller (top of image) as one class, not folder/subfolder + many separated files...

  6. 6 Posted by Oleg Borisov on 18 May, 2011 08:49 PM

    Oleg Borisov's Avatar

    Stray,

    Sure, coding is not general problem. My general problem is to understand - can I accumulate group of commands as one singleton-controller or not, and what problems in the future I will have, if I use this variant of event-command activity.

  7. 7 Posted by Stray on 18 May, 2011 08:57 PM

    Stray's Avatar

    Hi Oleg, technically you won't have problems, but many of us who have used controllers in the past find Commands to be a better way of doing things.

    As I said already - you can read in many many places about the Controllers vs Commands arguments. For example, this thread from Flex Coders: http://tech.groups.yahoo.com/group/flexcoders/message/1080

    Stray

  8. 8 Posted by Oleg Borisov on 18 May, 2011 09:06 PM

    Oleg Borisov's Avatar

    Hi Stray,

    Thanks,

    I created this topic for one point: understand the general question... Can I accumulate part of command in controller + map command as function, or Robotleg framework doesn't support / recommend it in the general practice.

    Ok, I try to create mixed activity: some code include in my Controllers, and some code use in the 'pure' commands interface. And will have the final decision after real work and support the big project...

    Thanks, mate.

  9. 9 Posted by Oleg Borisov on 18 May, 2011 09:12 PM

    Oleg Borisov's Avatar

    Stray, small question after all.

    If I have the 100 commands and map all commands in the Content.
    What is the optimum variant to organize this list of mapping? Map all commands in one base content for all project, or create some contents, etc?

  10. 10 Posted by Stray on 18 May, 2011 09:16 PM

    Stray's Avatar

    Search for "Bootstrap" in the existing list of questions - that'll help you out :)

    I'm off to bed here - but I think that'll explain how others do it.

    Stray

  11. 11 Posted by Oleg Borisov on 18 May, 2011 09:43 PM

    Oleg Borisov's Avatar

    Search for "Bootstrap"

    Thank you very much, go to study :)

  12. Stray closed this discussion on 25 May, 2011 08:27 AM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac