conceptual question: service events

lee's Avatar

lee

15 Feb, 2011 07:33 PM

Hi,

I'm new to the forum. Also kind of new to Robotlegs, so please pardon me if I exhibit any misunderstandings...

I'm having trouble conceptually with the relationship between the model and services. I have read that when a service produces a result, it can either update the model directly, or it can broadcast an event. For some reason, the idea of my service broadcasting events to the universe really disturbs me. Does this mean my view components can/should receive messages sent by a service (and vice versa)? Seems like anarchy.

I kind of want the model to be the central point of consolidation -- brokering calls to the service(s). I like the idea of my model code being a master blueprint for the application. I feel like there should be one file that someone can read to get a fair idea of how the application works?

Can somebody explain the benefits of allowing a service to work independently vs. coupling it to the model?

I should also mention that I am not presently using any sort of unit testing. I just want to use RobotLegs to give me greater control over my code.

Lee

  1. 1 Posted by Stray on 15 Feb, 2011 08:20 PM

    Stray's Avatar

    Hi Lee,

    if you'll forgive me for being honest... and I really don't want to come over as critical here... you've got some pretty unconventional ideas about what a model is!

    A model is just state. It represents some data, and might include some functionality for operations on that data, but it's certainly not a 'blue print' for your application - and I've never heard anyone refer to it in that way.

    In the example of this email application that I'm using to write a reply to you, there are probably models for the list of messages in each mail box, and for each account's settings etc.

    So... before you make your decision about whether your model and your service should be coupled, maybe it would be good to read around a bit and see what the meaning of 'model' that is shared by most developers is? If your terminology isn't the same as that in general use then it's going to be hard to make sense of the robotlegs documentation and examples. I actually wrote a blog post about this quite recently:

    http://www.xxcoder.net/whats-in-a-name-or-a-package

    And you could check out this flowchart for figuring out whether a class is a model, service or controller:

    http://twitdoc.com/view.asp?doc=28269818&key=key-12vb8axy1ff9i14o6amz&usr=stray_and_ruby&lcl=stray_and_ruby/rqyspi3i/mvcs_filter.pdf

    So - moving on to the rest of your question...

    There's definitely no anarchy in robotlegs!

    Services don't receive messages from anywhere - neither Services nor Models listen for events, they only dispatch them. We use the Command pattern to pick up events relevant to the application logic layer, and then the Commands wired to them act on the Model or Service API as required.

    Sometimes the view will be interested in those events too - for different reasons. You might have a view that updates a progress bar or feeds back information about what is going on with a remote call, reporting success or showing errors.

    The mediators can pick up any event they're interested in - then they act on the view API. Personally my mediators only receive and dispatch events, but sometimes people inject their model into a mediator against an interface that is getter-only - so the mediator has read-only access to the model.

    But... although we say 'the model' - in a robotlegs app there is rarely just one model. There might be several different models holding different aspects of application state / data.

    So - the pros and cons of coupling the model and the service are exactly the same as any other coupling decision. You're always balancing need-to-know against minimising your workload / the processor load. Often my services have direct access to a factory that processes the data so that it can populate the model.

    As for "there should be one file that someone can read to get a fair idea of how the application works" -... I totally agree. But that's a job for **documentation**, not code.

    In a small robotlegs app, the context is a good starting point for getting an overview of how events map to commands, and if your classes are well named then that gives some ideas about how your application works and what it does, but in a larger application usually you would break the injector wiring into multiple bootstrap commands.

    I hope some of that is helpful - apologies if I'm teaching you to suck eggs here, but the idea of the model being a central blueprint for the application is pretty whacky!

    Stray

  2. 2 Posted by lee on 15 Feb, 2011 09:09 PM

    lee's Avatar

    Hi Stray,

    Thank you SO much for taking the time to respond!

    Sounds like I've got it pretty wrong...Ugh, I'm trying not to get too discouraged. Attached is a simple app that I wrote when I was learning RobotLegs (you can see a live example at http://leebock.blogspot.com/). Do you think you could take a look at MyModel.as and let me know what DOESN'T belong there?

    Thanks again,

    Lee

  3. 3 Posted by Stray on 15 Feb, 2011 09:18 PM

    Stray's Avatar

    No problem - I'll take a look at it tomorrow (getting late in the UK now).

    I'm sure you're not too far off - after all, it works! But I'll see what I make of it and whether there are any places where you maybe need the same code but in a different place in order to fall into the patterns that other people are understanding and talking about, which will make it easier for you to pick it up.

    Don't be discouraged! The good news is that once you 'get it' robotlegs is really very simple and very powerful.

    Cheers,

    Stray

  4. 4 Posted by Lee Bock on 15 Feb, 2011 09:42 PM

    Lee Bock's Avatar

    Thanks, Stray! I feel better already!

    Lee

    -----Original Message-----
    From: Stray [mailto:[email blocked]]
    Sent: Tuesday, February 15, 2011 4:19 PM
    To: [email blocked]
    Subject: Re: conceptual question: service events [Problems]

  5. Support Staff 5 Posted by Stray on 16 Feb, 2011 09:17 PM

    Stray's Avatar

    Hi Lee,

    sorry - I should have spotted yesterday that you'd posted an fxp. I don't have / use flash builder so I can't open your project. Could you put it up as a zip instead? Or just upload the model that you're thinking about?

    Thanks,

    Stray

  6. 6 Posted by lee on 16 Feb, 2011 09:32 PM

    lee's Avatar

    Here you go. Thanks again!

    Lee

  7. Support Staff 7 Posted by Stray on 18 Feb, 2011 10:29 AM

    Stray's Avatar

    Hi Lee - sorry for the delay - busy week for me.

    So - I had a look, and I don't think there's any thing wrong with how you've built this app at all. Looks good to me on the whole. I only found one really important problem:

    • You must override the clone method in your custom events - otherwise the robotlegs shared dispatcher can end up losing them and their properties along the dispatch process. This is really important.

    The only small things I would suggest are:

    1. Instead of "MyModel" - maybe the model could have a name that describes the function it performs? Like "MapPointsModel" or "MapLocationsModel" or something?

    2. You could split the actual data - held in the _data property of the Model - into another class, and inject or pass this to the model to use as its data. That way your mapping model is separated from the data it holds, and could be used with a different data set. (I'm guessing you would have done this if it wasn't a demo.)

    3. You could change the ModelEvent to carry the _model.highlitRecord property with it as payload. This would me that you wouldn't need to inject the model into the ListMediator, and the ListMediator wouldn't need to know how to use the model api. This would also have the benefit of making the event more similar to the HighlightEvent - the whole process would be symmetrical in each direction, which is easier to understand because you only have to carry one set of logic in your head.

    4. Like wise, you could not inject the model into the SearchPanelMediator and so on, and instead pass the model records length / total records and so on in your events.

    5. You're changing text and visibility of parts of the SearchPanel directly in the SearchPanelMediator - maybe it would be better to expose an API on the SearchPanel for this?

    6. Event parameter order,

    rather than:

    SelectionEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false, searchString:String=null)
    

    I would make your own parameters go at the front:

    SelectionEvent(type:String, searchString:String, bubbles:Boolean=false, cancelable:Boolean=false)
    

    This avoids having to do:

    new SelectionEvent(SelectionEvent.SELECT, false, false, 'something');
    

    And instead you can just do

    new SelectionEvent(SelectionEvent.SELECT, 'something');
    

    Much nicer to read and also you can make the searchString not optional, which will help the compiler to catch mistakes.

    But I don't see that you abused the model in this example at all - it has a single responsibility, so that's the main thing.

    And all these things are fairly minor (apart from overriding clone in your events) - so don't get down about them!

    Stray

  8. 8 Posted by lee on 18 Feb, 2011 01:51 PM

    lee's Avatar

    Stray,

    Thank you SO MUCH. This was very generous of you to take the time to look at my code. I will incorporate your suggestions into the code ASAP and post any follow-ups. Thanks again!

    Lee

  9. Support Staff 9 Posted by Stray on 18 Feb, 2011 04:27 PM

    Stray's Avatar

    No problem - it was good of you to let me review it. You always learn something from a code review - both sides!

    Feel free to reopen this if you want to talk more when you're refactoring. I'm just closing it for now because it helps us stay on top of which posts are awaiting answers.

    Stray

  10. Stray closed this discussion on 18 Feb, 2011 04:27 PM.

  11. lee re-opened this discussion on 21 Feb, 2011 10:45 PM

  12. 10 Posted by lee on 21 Feb, 2011 10:48 PM

    lee's Avatar

    Hi Stray,

    I have made all of the modifications that you suggested. Thank you again!

    Attached is the updated code, in case anyone is interested.

    A follow-up question:

    Looking at the model and its responsibilities, I decided that "highlight" and "selection" were each self-contained ideas. Accordingly, I broke down the general model into two separate models, one to manage the highlight function/state and one to manage the selection function/state.

    Do you think this was going a bit too far? Or is it generally advisable to reduce models to smallest autonomous units? Can you envision a scenario in which I would regret this?

    Lee

  13. Support Staff 11 Posted by Stray on 02 Apr, 2011 11:32 AM

    Stray's Avatar

    Hi Lee,

    sorry - I meant to come back to you on this. I agree that it's useful to see 'hilight' and 'selection' as different things.

    I think it's partly a matter of preference. Personally I like small, very well defined classes. Some people find having a larger number of classes confusing, and prefer a less granular approach.

    I don't think I've ever regretted breaking things down so that they're individually very simple. But that's partly about my working style - I get interrupted a lot and I use TDD with small, well defined classes, so allow myself to be productive (get a task 'done') even when I only get half-an-hour to work on a project.

    Stray

  14. Stray closed this discussion on 02 May, 2011 03:22 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