do I need command chaining?

Andy's Avatar

Andy

29 Jun, 2012 09:23 AM

Hi there,

just getting started with RobotLegs over the last few days. I'm repeatedly gobsmacked when I come across a totally awesome solution of RobotLegs to a problem I've tackled in the paste without MVCS.

Afraid I'm struggling up the learning curve though! Steeeeeeep! I've a few Qs, hope that's ok:

-I load default settings for my app from an XML file via a LoadXMLService, driven my 'LoadDefaultSettingsCommand'. When the given XML file does not exist, my LoadDefaultSettingsCommand is told this and responds by running my 'CreateDefaultSettingsXMLService'. My issue is that it seems a waste of memory to load up the CreateDefaultSettingsXMLService as a singleton in my Context file before hand given and pass it to my Command via [Inject], given that it will only be used once in a while. Should I just create an instance of this service in my CreateDefaultSettingsXMLService and then destroy it after I have used it? Googling, it seems that command chaining is used in this scenerio but afraid I am not sure.

-it also seems a waste to keep code related to loading default settings in memory after the settings have been loaded. Is there a way to kill Services and commands once they are done with?

Thanks!
Andy.

Cheers,
Andy.

-

  1. Support Staff 1 Posted by Ondina D.F. on 29 Jun, 2012 01:15 PM

    Ondina D.F.'s Avatar

    Hi Andy,

    Of course you can create an instance of CreateDefaultSettingsXMLService where you need it and destroy it when you don’t need it anymore.

    But, you can also do something like this:

    -Context mappings:

    injector.map(ISomeService).toSingleton(SomeService);

    commandMap.mapEvent(SomeEvent.LOAD_SOMETHING, SomeCommand, SomeEvent);

    -In SomeCommand :

    [Inject] public var someService: ISomeService;

    then access someService.loadSomething()

    After SomeService has finished its job, it dispatches an event triggering an

    -UnmapSomeServiceCommand, which will do:

    injector.unmap(ISomeService); // ==> SomeService gets gc-ed

    And, if you want, you can unmap the commands as well:

    commandMap.unmapEvent(SomeEvent.LOAD_SOMETHING, SomeCommand, SomeEvent);

    But, as you probably already know, commands won’t be kept in memory after their execute() has run.

    HTH
    Ondina

  2. 2 Posted by andytwoods on 29 Jun, 2012 02:30 PM

    andytwoods's Avatar

    Thanks! Super quick reply too :)
    I ended up with something similar to what you suggest.
    In my Context:
    injector.mapSingleton(SaveDefaultsService);
    and
    commandMap.mapEvent(DefaultsEvent.CREATE_DEFAULTS, CreateFreshDefaultsCommand,DefaultsEvent);

    I am guessing that it's overkill to use a command in my above code when a service can just call another service. Guessing to it is better practice not to make my singleton 'accessible to all' and just accessible to what needs it. I'll update to your code :)

    Slowly things are becoming more understandable to me. Cheers!

  3. Support Staff 3 Posted by Ondina D.F. on 29 Jun, 2012 02:57 PM

    Ondina D.F.'s Avatar

    No problem, Andy:)
    Maybe my first statement was a bit misleading.
    I should have warned you that creating an instance of CreateDefaultSettingsXMLService in another service may be problematic.
    How will you know when to destroy it, in case of an asynchronous response, and where are you intending to destroy it? Or are both services disposable after running them?
    Besides, it’s not quite “nice” to call a service from another service, if you want to strictly follow the best practices ;)
    But, if you really need to do it like that, just do it. You can decide later whether it’s a good approach or not.

  4. 4 Posted by andytwoods on 02 Jul, 2012 05:47 AM

    andytwoods's Avatar

    Hi there,
    afraid it's me again :)
    Digesting this part of your first message:

    "-Context mappings: injector.map(ISomeService).toSingleton(SomeService);
    commandMap.mapEvent(SomeEvent.LOAD_SOMETHING, SomeCommand, SomeEvent);
    -In SomeCommand : [Inject] public var someService: ISomeService; then access someService.loadSomething()"

    You've probably guessed it but I've a Q or 2!:
    -does RobotLegs only instantiate a service when it is called? Most likely this is a stupid question :-) -regarding "injector.map(ISomeService).toSingleton(SomeService);" Why use ISomeService and not just injector.mapSingleton(SomeService)? Is there a memory benefit of not referring to the 'full fat' class and referring to it's interface?

    Thanks!

  5. 5 Posted by andytwoods on 02 Jul, 2012 06:08 AM

    andytwoods's Avatar

    Hi,
    another quick Q:
    " injector.map(ISomeService).toSingleton(SomeService);" guessing this is robotlegs 2? map method not available to me (robotlegs 1). cheers,
    Andy.

  6. 6 Posted by andytwoods on 02 Jul, 2012 06:58 AM

    andytwoods's Avatar

    OMG This is so amazingly incredibly awesome:
    [PostConstruct]

    For anyone reading this and wondering, calls any function after everything has been loaded.
    https://github.com/robotlegs/robotlegs-framework/wiki/Robotlegs-Int...

  7. Support Staff 7 Posted by Ondina D.F. on 02 Jul, 2012 02:10 PM

    Ondina D.F.'s Avatar

    Hey Andy,

    injector.map(ISomeService).toSingleton(SomeService);" guessing this is robotlegs 2? map method not available to me

    Right, this is rl 2 syntax. My bad, I was working on an rl2 project by the time I answered your question, and the more intuitive syntax used in rl2 was still fresh in my mind.

    For rl1 the mapping would look like this:
    injector.mapSingletonOf(ISomeService, SomeService);

    Regarding the question about interfaces:
    It’s impossible for me to cover all the benefits of “Programming to an interface, not an implementation“ in this post. The topic is too complex, and besides there are a multitude of in-depth articles and books on the subject, written by experts. So I’ll just mention a few things (rather keywords that can be used for further research) that come to mind:

    • using interfaces enables code reuse, which can minimize duplicate and repetitive code, the code becomes flexible, managing dependencies is easier, your application is easily maintainable

    • using interfaces makes it possible to follow the SOLID principle of OOP and OOD

    • interfaces are used in several design patterns

    • interfaces as APIs

    • interfaces keep the coupling minimal

    • encapsulating the implementation is a good thing

    • you can be sure that a certain functionality will work in a standardized way

    • type safety

    • you get compiler errors when the class that implements an interface does not implement all the methods declared in the interface, and that’s good when building an application that will be extended by another developer or used by third parties

    • it is easier to test classes in isolation and to use mock objects when real objects are not available

    • generalization is a good thing, in OOP ;)

    • polymorphic capabilities

    • allows the use of interchangeable behaviors, variation of implementation

    • using an interface allows a service to be swapped for another one that implements the same interface, i.e., if IAssetsLoader is implemented by SQLAssetsLoader , XmlAssetsLoader, MockAssetsLoader , all you have to do is replace
      injector.mapSingletonOf(IAssetsLoader, SQLAssetsLoader);
      with
      injector.mapSingletonOf(IAssetsLoader, XmlAssetsLoader);
      or
      injector.mapSingletonOf(IAssetsLoader, MockAssetsLoader);// a dummy class used to mimic services’ behavior – used in unit testing
      This way your Application doesn’t have to care where the data comes from.

    Sorry, if you already know all of this, or if the random listing was confusing! :)

  8. 8 Posted by andytwoods on 02 Jul, 2012 03:18 PM

    andytwoods's Avatar

    thanks for all your help! I'm still very much a newbie at this sort of thing :-)

  9. Support Staff 9 Posted by Ondina D.F. on 02 Jul, 2012 04:46 PM

    Ondina D.F.'s Avatar

    You’re welcome, Andy!

    And don’t worry, compared to the design patterns gods and geniuses out there (GoF, Fowler and many others) we, ordinary (mortals) coders, will be Noobs Forever;) No matter how advanced we get, they’ll be always ahead of us, unless the best practices and design patterns change over time…
    Besides, being a perpetual newbie in a programming/platform field or another is our fate as developers, am I right?

    You can close the discussion, in case your original problem has been solved. Please open new threads for new issues.
    Thank you :)

  10. Ondina D.F. closed this discussion on 05 Jul, 2012 10:08 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