Examples are not clear enough – people use events+commands in a wrong way

pavel.fljot's Avatar

pavel.fljot

01 Sep, 2014 05:36 PM

Do you have framework events (here and after I use "events" for both events and signals) that looks like DO_SOMETHING?
Probably, you do it all wrong :(

Recently I've been working with two different teams on different projects, and, to my surprise, both of the teams and team-lead developers were using events/signals+commands in a slightly wrong (or non-optimal) way. Why? Well basically because examples taught them so.

Here's what they were doing. They use framework events not in a passive form (like "SOMETHING_DONE"), but in an imperative form (like "DO_SOMETHING"). Not only the naming is the issue, but where and how they were dispatching them. They're mapped one-to-one to corresponding commands ("MyEvent.DO_SOMETHING" -> "DoSomethingCommand") and dispatched in the mediators, services, models and in other commands.

Do you see the problem? By doing so, you basically put part of the logic directly in the place, where you dispatch event. Dispatching such event is almost the same as executing command manually. I say almost, because you can actually unmap command or map different ones if you have some sort of modular app. But anyway, conceptually, dispatching such event means placing the app flow logic there. This way you dispatch event to perform desired action.

And also it makes your app architecture more coupled. You dispatch DO_SOMETHING in more than one place of your app, which triggers DoSomethingCommand. But what if you also want to execute DoSomethingElseCommand on that event, but only when it's dispatched from one certain view?

Better way:

Make your scope of responsibility smaller. Dispatch what HAPPENED. Decide what should happen next via mapping. You can map one event to several commands (app actions themselves + tracking/logging), you can map same command to several events – you can make parts of your app decoupled, therefore more flexible and more clean and transparent.


I wasn't sure which category this topic fits best to, so I ended up with "Feedback" because you might be not aware of this issue and I think you should make this thing a bit more clear to developers.

  1. Support Staff 1 Posted by Ondina D.F. on 08 Sep, 2014 12:15 PM

    Ondina D.F.'s Avatar

    It has been a very busy work (last)week and week-end, that's why I couldn't respond earlier. Sorry for that.
    Today, I wanted to make it up to you, so I've spent almost the entire morning on writing down my thoughts, and to my surprise I ended up with a message spreading over several pages. I'll split it up into 2 messages. The second one contains a few definitions and citations from different sources, mostly books, that I found to be interesting.

    Thank you for the feed-back.
    That's an interesting topic, but very opinionated.
    If there were only one valid approach to solving any given problem, life would be much easier... and/or boring;)

    There is a lot to be said on the topic! Of course, what I'll be saying next, will only scratch the surface, and, most importantly, it will reflect only my opinions, based on personal experience and reading around the subject.

    Messaging is a very complex technology, and Events, as we know them from as3, are just one of the many ways of communication within an application or between applications.
    As3 Events are very powerful, but, sadly, they are limited in many aspects. Other programming languages are equipped with more than one messaging mechanism, but we have only the Event class at our disposal. As3Signals try to compensate for the shortcomings of Events, but that's another story.

    I think that many of our problems, as developers, are caused by the fact that concepts/patterns/terms like Event, Notification, Message, Signal, Request, Response, Action, Command, State have various definitions, interpretations and usage in different programming languages or developing platforms or even within one and the same platform/language/framework...
    Since it's obviously difficult to reach a consensus on definitions, naming, or standards, i.e. on the theoretical part of things, the more difficult it is, if not impossible, to find a one-size-fits-all practical solution.
    What sounds good in theory, might be hard to implement in such a way that the requirements of a specific project are perfectly met. Very often, only time can tell how good an approach was, or if another one would have been better.

    If you take a look at the examples from the Robotlegs book, kanban and mosaictool (that you can find on github), you can see 2 different approaches concerning the naming of event-types. Both being valid, in my opinion. Kanban uses imperative, whilst mosaictool uses past tense.
    Kanban is using events rather as a request for an action that will occur in the future(a command). Mosaictool is using events to inform interested parties about a state change, or about an event(action) that took place already.

    Even though I'm a proponent of using past tense for Event types to indicate that something has already happened, and that's the way I've used Events in most of my projects, I don't see a problem in using as3 custom events as a Request for an action. (See some definitions for Event and Request further down).

    I think, what really matters is that the names are descriptive enough, that they aren't too long nor too short, that they carry the same meaning for all participants in a project (developers), and that the chosen naming convention will be followed throughout the entire project. (see the part about naming convention bellow)

    A mapping from mosaictool:

    commandMap.
    mapEvent(DesignLoadEvent.LOAD_REQUESTED, 
    LoadDesignCommand, DesignLoadEvent);
    

    What is LOAD_REQUESTED representing? An Event, a Request, or a State?

    When using commands, an event type like DesignLoadEvent.LOAD_REQUESTED, is more like a Request for an action or a set of actions, that may or will be performed inside of a LoadDesignCommand, in the future. It is used in past tense, but the moment such an event is dispatched, the actual meaning of load requested is: I (the user, or the component/class) wish to get some data, while I don't care who, or what will do that for me. But, a wish or a request is actually a directive, an order or an instruction to execute a task.
    What really happened was a button click, but LOAD_REQUESTED is translating the event (what happened) into a request (load).
    Now, if we think of that request as being an action that has occurred, i.e. an event: the user requested data (LOAD_REQUESTED, past tense), where something like WAITING_FOR_DATA (gerund) would be the state of that component/class until it receives the data, LoadDesignCommand would be the future action, or the handler of the LOAD_REQUESTED event.
    But, the Command is just an intermediary that orchestrates other activities.

    Let's analyse a use case, that is intentionally very simple and at the same time a little bit absurd.
    A View presenting a single button to the user. The button is labelled 'Load'. And there is also a comment like 'You have 30 seconds to decide, whether you click the button or not'.
    Here, the View can detect 2 things: the occurrence of loadButtonClicked, and the non-occurrence of the loadButtonClicked, which could be a timeout event.
    Anyway, if the user, presumably a human, clicks the button, something is expected to happen: some data should be presented in the View, as text, graphics, sound, etc. Maybe the data is already there, in the View, but not visible (or audible) until the button click event occurs.
    The first action, a click on the button, is reported as an event that has happened-loadButtonClicked, and as a consequence an image is changing its state from hidden to visible. In this case the image can be seen as being the data, and changing its visibility, the action. Of course, I expect you to say that the label of the button is misleading. Load? Wouldn't it be better to call it 'Show', if the image was hidden? Yes, it would be better to call it 'Show'. But, wouldn't it be even better if the user would be properly informed what to expect, when the button click occurs? Yes, if there is no other contextual information from which the user can deduce the meaning of the button. If the application's name is something like Image Processing, Image Gallery, Family Photos or alike, the meaning of show or load would be already more clear. But, not entirely, because we, as users of the app, still don't know if it will be a single image, a list of images to select from, or all images presented at once in a grid. So, the naming problem starts wit the GUI. Long, descriptive names for buttons or other interactive components can be a problem from a layout point of view. Contextual information is a way to solve it: tool-tips, additional labels, title of a panel that contains the buttons, and so on. Putting things in(to) context is an essential part of communication of any kind, where 'context' is extra information that helps someone to understand something better. I'm putting emphasis on this aspect because when we talk about naming classes, variables, or anything else in our code, we often get caught in focusing only on the names of some parts in the app and forget about the additional, contextual information or about the overall information flow.
    It's a known fact, that OOP and design patterns tend to obfuscate the flow of information or data or control and/or the cooperation between classes within an application or program more than when using other programming techniques. To understand the flow we need to know how the patterns work, or how a certain framework is making use of them, we need to look at the structure of a project, packages and libraries, and yes, at the names of classes, variables, constants...

    For someone who doesn't know anything about robotlegs, or even the command pattern, the following mapping doesn't make much sense:

    commandMap.mapEvent(DesignCreationEvent.DESIGN_CREATED, UpdateCurrentDesignOnConfigCommand, NamedDesignEvent);

    Or, in the initial example, DesignLoadEvent.LOAD_REQUESTED->LoadDesignCommand,
    will the command load the design? For robotlegs users the answer is pretty clear: no, the command will only orchestrate the process of loading, and most probably a Service will be the (final) actor forwarding the request to a database server or using the file system to load data/file.

    But for outsiders, it doesn't matter that the LOAD_REQUESTED is meant to represent something that has happened, or that the word 'command' in LoadDesignCommand implies some action, because the contextual information is missing. Who raised the event, who will carry out the loading?
    Robotlegs users will find out that LoadSelectorMediator is 'translating' LoadSelector's(the view) event, LoadSelectorEvent.LOAD_CLICKED, into DesignLoadEvent.LOAD_REQUESTED and then is dispatching it to trigger LoadDesignCommand, which will access a method on DesignSolLoadingService. loadDesign(), which will eventually dispatch a DesignLoadEvent.LOAD_COMPLETED, which will
    1. trigger UpdateCurrentDesignOnConfigCommand, which will access ConfigModel. namedDesignEvent()
    - which in turn will dispatch DesignListEvent.CHANGED-> LoadSelectorMediator. passDesignListToView()

    • and ConfigChangedEvent.CHANGED will trigger the flow-> SaveConfigCommand-> MosaicConfigSolSavingService-> MosaicConfigServiceEvent.SAVE_COMPLETED
    • and would be listened to by DesignNameViewMediator, which will access DesignNameView. updateViewText

    That was a pretty complex work flow, where many actors were involved in responding to the request initiated by the load button click. About 5 events were used to transport messages from one part of the app to another.

    Other scenarios may be more straightforward. A Load button clicked->load command->load service->db/file system->load complete event + data as payload->mediator->view->present data to user. It is a cycle. The view having the load button would be useless if it wouldn't get the data that it has requested. So, maybe in this case having a LOAD_IMAGE event type, instead of LOAD_IMAGE_REQUESTED wouldn't be that bad of a name, because it is indeed an initiator of an action with an expected and predictable result: image. It is for sure a request-response cycle, and the request is implicit. The view is requesting an image, the service is responding and sending that image to the mediator->view. LOAD_IMAGE paired with IMAGE_LOADED makes sense, and are signalling the start and the end of a loading process. The View 'knows' what it wants.

    If we wanted to be precise, we would indeed name the starting event type
    LOAD_IMAGE_REQUEST and the responding one LOAD_IMAGE_RESPONSE or result.
    Any variations on the naming of those 2 event types would be ok, in my opinion, if they are clear to the programmer(s). The choice between using verbs or substantives shouldn't be imposed by frameworks or patterns. The given names should make sense in the context of the entire application.

    In yet another scenario, a View is reporting a change of its own state or of its components. It doesn't make any decisions. It just raises an event, informing everyone interested that, for example, the size of a component has changed. What happens because of that is not important to the View. So, SIZE_CHANGED would be an information about something that has happened. Other actors would react to this kind of information and do whatever they have to do. Here, the decision to take an action lies elsewhere in the application. That would be an EVENT. The view raising the event would continue to function as it should and wouldn't be affected by what happens elsewhere in the application.

    In the LOAD_IMAGE scenario, the decision to take an action lies with the view. It is a REQUEST for an action. The view depends on this action and the view is useless if nothing happens. The View is part of a process, that it starts with itself (button clicked) and it ends with itself (show image to the user).
    LOAD is an initiator of a loading process, or a sequence of actions: loading process started, loading in progress, loading finished/loading failed...
    If I want to re-use this View, I certainly want it to do exactly one and the same thing: show image(s), and thus the Load button will always be present and will always have the same role.
    In my opinion, the View is allowed to be 'smart' and 'active' in such a case, as opposed to the View reporting a size change event, which is 'ignorant' of other processes within the application.

    Then there is the StateMachine approach, which I won't go into detail about. Just wanted to mention that a statemachine ACTION can be associated /mapped with/to a command. Almost everything inside of an application is a change in state(s). With a SM the flow of information / control is often easier to understand, just by looking at the class that configures the FSM.

    We can see variations in usage of event classes, as well. Some prefer to group event types together inside of a single event class. Some others prefer to have separate classes for each type of event.

    Then there are variations in naming the custom event class itself. Sometimes it is associated with a group of functionalities, like ConfigurationEvent, or with an entity, like UserEvent, or cross-cutting concerns, like LoggingEvent.

    My conclusion is, that no matter which naming convention we are using, as3 Events provide insufficient means to address all possible scenarios or requirements in an application, and are prone to be misused in a way or another, because as3 lacks in other forms of communication, or messaging in general.
    Maybe we need something like an ActionTrigger or a CommandMessage next to our typical Events. Anyway, something to differentiate between informing about past occurrences and triggering /initiating some behaviour/action/activity/processes...

    Another conclusion of mine is that, yes, you are right, naming conventions are very, very important, but they are just one piece of the puzzle.

    Whenever it comes to evaluating something, be it a program, lab results, or human behaviour in general, I like to bring up the difference between cut-offs and reference ranges. A cut-off implies that only one-sided values are normal or valid or good (below or above the cut-off value). A range is a set of 'normal' values between a min and a max value.
    Saying that only one way to solve a problem is valid, is like a cut-off. I'm a fan of reference ranges and interpretations using SDs (standard deviation) :)

    As I said before, I usually use past tense, but I think that both, past tense and imperative for event types, are ok depending on the context of the application/project (I mean conditions, circumstances, settings, kind of a project, contextual information, not the rl-context).
    Other than that, I agree with almost all you said in your message.

    A consensus on the best usage of Events + rl could be reached if there were more than 2 or 3 people expressing their opinions on the matter, but, as you know, there are only a few as3 users left and even less rl users...
    Anyway, thank you for your thoughts and I encourage you to express your opinions about other aspects of rl, if you want. Constructive feed-back is always welcome!

  2. Support Staff 2 Posted by Ondina D.F. on 08 Sep, 2014 12:17 PM

    Ondina D.F.'s Avatar

    DEFINITIONS

    ---- Definition of Event:

    -Dictionaries definition: an event is something that happens, something that takes place, an occurrence, something that occurs in a certain place during a particular interval of time.

    -DOM Level 3 Events Specification

    Events are typically dispatched by the implementation as a result of a user action, in response to the completion of a task, or to signal progress during asynchronous activity (such as a network request). Some events can be used to control the behavior that the implementation MAY take next (or undo an action that the implementation already took).

    An activation trigger is a user action or an event which indicates to the implementation that an activation behavior SHOULD be initiated.

    -Adobe (which is based on DOM 3 specifications)

    Events let a developer know when something happens within an application.
    The Event class is an ActionScript class with properties that contain information about the event that occurred.

    ---- Event-based, Event-driven

    -Event-Based Programming - Taking Events to the Limit - by Ted Faison A software system is said to be event-based if its parts interact primarily using event notifications. In this context, a part is anything containing code, such as a module of functions, an object, or a component made up by classes and objects. Notifications are basically signals sent from one part to another, in response to an event.

    An event-based system is made up of a collection of independent parts that interact using event notifications. A system designed this way is easier to build, test, and maintain than a traditional one. The larger the system, the greater the benefits of an event-based approach.
    What problem does an event-based design try to solve? The answer is this: coupling. An event-based design tries to reduce as much as possible the coupling in a system.

    In ordinary language, an event is an occurrence of some kind, while a notification is a message informing the recipient that something (presumably important) has happened. In the software context, the definitions of events and notifications are inextricably bound, with one being defined in terms of the other. Events are a cause; notifications are an effect.

    An event is a detectable condition that can trigger a notification.
    A notification is an event-triggered signal sent to a run-time–defined recipient.

    OO languages use their own lexicon with events. .... People often use the word event when they are really talking about a notification, probably because what the sender calls a notification can be considered an event by the receiver....
    Notifications sent by one component sometimes trigger events in others, producing a sequence of notifications and events that propagate through a system in a chain reaction. One component’s notifications are another component’s events....

    -Event Processing in Action - by Opher Etzion and Peter An event is an indication of something that has already happened, whereas a request, as its name implies, expresses the requestor’s wish that something specific should happen in the future.

    Event-based programming, also called event-driven architecture (EDA) is an architectural style in which one or more components in a software system execute in response to receiving one or more event notifications.

    -Software Modeling and Design - Hassan Gomaa An event is an occurrence at a point in time; it is also known as a discrete event,
    discrete signal, or stimulus. An event is an atomic occurrence (not interruptible) and
    conceptually has zero duration. Examples of events are Card Inserted, Pin Entered,
    and Door Opened.

    A state represents a recognizable situation that exists over an interval of time.
    Whereas an event occurs at a point in time, a finite state machine is in a given state
    over an interval of time. The arrival of an event at the finite state machine usually
    causes a transition from one state to another.

    Some states represent the state machine waiting for an event from the external
    environment; for example, the state Waiting for PIN is the state in which the state
    machine is waiting for the customer to enter the PIN

    Other states represent situations in which the state machine is waiting for a response from
    another part of the system. For example, Validating PIN is the state in which the
    customer PIN is being checked by the system; the next event will indicate whether
    the validation succeeded or not

    Associated with a state transition is an optional output action. An action is a computation that executes as a result of a state transition. Whereas an event is the cause of a state transition, an action is the effect of the transition. An action is triggered at a state transition.

    A transition action is an action that is a result of a transition from one state to another

    -Enterprise Integration Patterns - by Gregor Hohpe, Bobby Woolf Messaging is a technology that enables high-speed, asynchronous, program-to-program
    communication with reliable delivery. Programs communicate by sending packets of data called messages to each other.

    The message itself is simply some sort of data structure—such as a string, a byte array, a record, or an object. It can be interpreted simply as data, as the description of a command to be invoked on the receiver, or as the description of an event that occurred in the sender.

    ---- Definition of Command - Wikipedia

    The Command also known as Action, Transaction - is a behavioural design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time.

    ---- Definition of request-response

    Wikipedia
    Request–response or request–reply is one of the basic methods computers use to communicate to each other. When using request–response, the first computer sends a request for some data and the second computer responds to the request. Usually there is a series of such interchanges until the complete message is sent.

    GoF
    request = An object performs an operation when it receives a corresponding request from another object. A common synonym for request is message.
    Requests are the only way to get an object to execute an operation. Operations are the only way to change an object's internal data. Because of these restrictions, the object's internal state is said to be encapsulated;

    --- Naming conventions

    The Object-Oriented Thought Process - by Matt Weisfeld
    There are many naming conventions, and the convention you choose is not as important as choosing one and sticking to it. However, when you choose a convention, make sure that when you create classes, attributes, and method names, you not only follow the convention, but also make the names descriptive. When someone reads the name, he should be able to tell from the name what the object represents. These naming conventions are often dictated by the
    coding standards at various organizations.
    Good Naming
    Make sure that a naming convention makes sense. Often, people go overboard and create
    conventions that might make sense to them, but are totally incomprehensible to others.
    Take care when forcing other to conform to a convention. Make sure that the conventions
    are sensible and that everyone involved understands the intent behind them.

  3. 3 Posted by pavel.fljot on 24 Sep, 2014 11:39 AM

    pavel.fljot's Avatar

    Heh. Ondina delivers))

    Thank you very much for the profound answer.
    I wasn't clear enough in my explanation, so we got it a bit too away into naming question. But you mentioned request concept – and this is exactly what I was talking about. Shame on me, I haven't called it by name.

    So let's focus on the topic of using Events/Signals as request for an action (Command), which I mostly find "better not".

    First of all (not to piss off people who find it useful) – yes, it might be useful sometimes. Can't really think of such a case atm, but still – please make it clear (via naming, obviously), that it is a REQUEST.

    But why I started this topic is because I see people use it as request in an ambiguous (vague) way or more in a command-ish way (thus the naming question arise, not like REQUEST_LOAD, but LOAD). And, mainly, they use it where it would better not to use it.

    And here's why I think in most cases it's better to inform about something happened, rather than request/command to do something:

    1. Splitting responsibilities. (in short: don't dispatch requests from V or M (S))

    We agreed to put domain logic (and "app flow" is kinda part that thing, right?) into controller layer. Spreading logic across other layers (views and models) makes everything messy. This is one of the core agreements when implementing components (M, V, C, (S)) of your application.
    What happens when you make requests from M, V, (S)? You put this kind of logic there. V or M is commanding or requesting to load something? – You make it responsible for app flow.
    One may think "But it's just a request, it's not necessary that it will lead to some action. So technically we don't initiate the action." But think of the situation when we need to change app behaviour – in this case we would need to update V or M (S) layer!

    In apps I've seen not only it happens ALL THE TIME, but naming doesn't indicate that it is request. It's rather named something like BlahBlahCommandEvent.

    2. Scope of responsibility. (in short: make atomic Commands)

    Basically it's a side of "single responsibility" concept. Dispatching request Event/Signal means that your piece of code (Command) is not only responsible for one thing it does (e.g. composing some data and updating certain Model), but also it's aware (and in a way responsible) of what's coming next.
    Narrowing down focus (scope of responsibility) helps to make Commands reusable, decreases code-duplication and helps with decoupling.

    I will think of some nice examples later, they will definitely help.
    Yet any comments are welcome meanwhile! As it could help to improve examples.

  4. Support Staff 4 Posted by Ondina D.F. on 30 Sep, 2014 09:21 AM

    Ondina D.F.'s Avatar

    Hi Pavel,

    Yeah, I was surprised myself by the length of my answer ;)

    I can't wait to see your demos/examples! It would be good if they were based on robotlegs 2, because there aren't enough demos for that version of the framework, but a rl1 variant would do it too, since it would be about general principles/design patterns.
    Thank you in advance for your efforts :)

    Cheers,
    Ondina

  5. 5 Posted by pavel.fljot on 15 Dec, 2014 04:32 PM

    pavel.fljot's Avatar

    Not forgotten!

    So here's what people do (I'll write in pseudo code, I hope everyone who reads this will understand).

    1. Regarding making mediators/views decide what should happen in the app:
    Context
    {
        commandMap.map(CommandEvent.DO_STUFF, DoStuffCommand);
    }
    
    MyMediator
    {
        view.somethingClicked -> eventDispatcher.dispatchEvent(new CommandEvent(CommandEvent.DO_STUFF));
    }
    

    Where DoStuffCommand literally does that stuff, e.g. "do stuff" can be "close app" or "start race" (imagine a racing game). So we basically make view layer decide how app should behave. We mix view and controller together.
    How can it be done better? Dispatch what has happened in the view, not what to do. When you map event-to-command as one-to-one, you make this strong logic binding. What if you want not only start a race, but to log the UI interaction? What if you want to perform some side-task, which is not directly related to the race itself? Either you will dispatch multiple events (for each of that extra functionality), or you will add all this extra func into DoStuffCommand, making it not about doing stuff anymore, but doing EVERYTHING. What if you want not to do stuff immediately, but first finish something which is already running or show some dialog first?

    Decouple VIEW from the CONTROLLER by using mapping. Don't make controllers out of your view layer.

  6. 6 Posted by pavel.fljot on 16 Dec, 2014 02:55 PM

    pavel.fljot's Avatar
    1. Regarding scope of responsibility (in addition to the previous point)

    In another project I see people doing this kind of things:

    SomeBaseLogicCommand
    {
        some logic, calculations...
        if (condition1)
        {
            foobar
        }
        else if (condition2)
        {
            dispatch(GameCommandEvent.DO_ANOTHER_THING);
        }
        else if (condition3)
        {
            dispatch(GameCommandEvent.DO_THIRD_THING);
        }
    }
    
    ConcreteGameLogicCommand extends SomeBaseLogicCommand
    {
        super.execute();
        dispatch(ConcreteGameCommandEvent.DO_ANOTHER_SIDE_FUNCTIONALITY);
    }
    

    Some comments first to clarify general situation regarding commands.
    Let's say this is a set of casino games, where all games have some common base logic in base command classes (e.g. BaseClearBetsCommand) and some extra functionality or implementation details in subclasses (e.g. RouletteClearBetsCommand extends BaseClearBetsCommand).
    This is the reason, why they don't call other commands inside command directly (like DirectCommandMap in Robotlegs2), but rather dispatch events, which are mapped to the right concrete subcommand in concrete game contexts (one-to-one event-to-command mapping, therefore "CommandEvent").

    And here's what bugs me.

    First of all, the fact that command is responsible for several things – for it's own internal business and some side(parallel) or following functionality. By side-functionality I mean something that is totally unrelated, but, given functional requirements, should also happen – see dispatch in ConcreteGameLogicCommand above. For example, in BlackJack game they have to ??? side bets when clearing unconfirmed bets. So here's what they do:

    public class BlackJackClearUnconfirmedBetsCommand extends GameClearUnconfirmedBetsCommand
    {
        override public function execute():void
        {
            super.execute();
            dispatch(new BlackJackCommandEvent(BlackJackCommandEvent.CHECK_SIDE_BETS));// will trigger BlackJackCheckSideBetsCommand
        }
    }
    

    Better way: instead of creating subclasses and dispatching events, simply create this mapping

    // pseudocode
    map(BETS_CLEARED).to(BlackJackCheckSideBetsCommand);
    

    This makes it more readable, decoupled and flexible, right?

    Another similar example is, let's say, when you start a race in a racing game, you want music "from the main menu" to stop. You would listen to some kind of RACE_STARTED event rather than caring about turning off the music from the command, where you actually do racing start business, right?

    Okay, that was about side (parallel, directly-unrelated) functionality.

    About calling commands from the command in the following posting...

  7. 7 Posted by pavel.fljot on 16 Dec, 2014 03:19 PM

    pavel.fljot's Avatar

    AAAHHH damn it. No edits?

  8. 8 Posted by pavel.fljot on 17 Dec, 2014 09:44 AM

    pavel.fljot's Avatar

    So, regarding calling commands from commands, directly or indirectly (via event/signal).

    It feels a bit wrong if 2nd command invocation looks like this:

    ServerResponseHandlingCommand
    {
        update model A
        update model B
        if (condition)
        {
            invoke another command
        }
        more logic
    }
    
    But I'm not sure how to make it better =( Any suggestions?
    I think what bothers me mostly is that this ServerResponseHandlingCommand is more of a big handler, it doesn't do anything specific, but rather does everything that should happen in response to "server event". So much not atomic. But how should it be then?

    Thank you for attention)

  9. Support Staff 9 Posted by Ondina D.F. on 17 Dec, 2014 02:55 PM

    Ondina D.F.'s Avatar

    Hey Pavel,

    I completely agree with you, having lots of else if or big switch statements inside of a class is a sign that the class is doing too much, having too many responsibilities.

    Utilities like MacroBot or StateMachine are meant to help with complex scenarios, where there is a need of controlling the order of many actions, or where actions can be triggered in response to a state change.

    I think MacroBot utility could solve the handling of atomic tasks (update model A, update model B...)
    inside your ServerResponseHandlingCommand, where each task would be another command and ServerResponseHandlingCommand would be a MacroCommand. But maybe you've tried it already and it is not what you need?

    In robotlegs 2, you can map commands .withGuards ( which can prevent a command from executing depending on certain conditions). This might come in handy for some use cases. Just wanted to mention this feature, in case you didn't know about it.

    AAAHHH damn it. No edits?

    Is the Edit button on each of your posts not working? Or you can't see any Edit buttons when you log in?

    I've edited your message for you. I hope it is now the way you wanted it to be:)

    Ondina

  10. Ondina D.F. closed this discussion on 28 Oct, 2015 03:52 PM.

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