Why model is "singleton"

Amnesiac's Avatar

Amnesiac

13 Jan, 2012 10:52 AM

Hi,

I used to have model classes that stores some data and have inside own childs ex:

class News{
    private var _title:String;
    private var _content:String;
    private var _author:User;
    private var _comments:Array;
    public function get comments():Array{
        return _comments;
    }
    public function getCommentById(id:int):Comment
    {
        return _comments[id] as Comment;
    }
}

And comment class:

class Comment{
    private var _content:String;
    private var _author:User;
    // getters/setters....
}

And when i needed a news with comments and comments with authors:

var comments:Array = news.comments;
for(var i:int = 0; i<comments; i++)
{
    var comment:Comment = comments[i] as Comment;
    trace(comment.author.name);
}

That was very easy, every News has instances of comments and user that was needed, and Comment has instance of User...

But in robotlegs (if im not wrong) I should have one NewsModel, CommentModel and UserModel with several ValueObjects.
Now if i want to get News i need to call newsModel.getNews(id) than: commentModel.getCommentsByNews(news) and than for every comment userModel.getUserById(userId) ... this is strange for me :/

I think I'm on wrong path... help please

Showing page 2 out of 2. View the first page

  1. Support Staff 31 Posted by Ondina D.F. on 21 Jan, 2012 12:42 PM

    Ondina D.F.'s Avatar

    Hi Amnesiac:)
    I've downloaded the app. I will take a look at it and answer as soon as possible.

  2. Support Staff 32 Posted by Ondina D.F. on 21 Jan, 2012 04:50 PM

    Ondina D.F.'s Avatar

    Letting you know that I’m making some changes to your code to have it work with your Models (the way you configured the Models). There are also other things that I’ve modified while going through the files. On the whole, your application (folders, classes, etc) looks good :)

    I won’t be able to finish everything today, though. I’ll continue tomorrow, as time permits, and on Monday (at the latest) I’ll tell you more about my progress and attach the modified code.

    o.k.?

  3. 33 Posted by Amnesiac on 21 Jan, 2012 05:04 PM

    Amnesiac's Avatar

    Thanks very much for your help, time and patience :) I'm waiting for code modifed by You and going forward with my app :)
    Wysłano korzystając z usługi Era mail wersja BlackBerry®

  4. Support Staff 34 Posted by Ondina D.F. on 22 Jan, 2012 05:33 PM

    Ondina D.F.'s Avatar

    See attachment for the modified app. There is a lot more to do and to refactor, but I’m sure you are curious to see at least a part of it, so you can have it now.
    I’ll comment on it tomorrow in case you don’t understand the flow from the trace statements and comments in code.

  5. 35 Posted by Amnesiac on 22 Jan, 2012 05:51 PM

    Amnesiac's Avatar

    Thx. See a lot of changes. Must take a deep look at code :)

  6. Support Staff 36 Posted by Ondina D.F. on 23 Jan, 2012 12:13 PM

    Ondina D.F.'s Avatar

    As I said, there are more things that could be done better or differently, but I was concentrating on making it work, while preserving as much of your app’s architecture as I could.

    Now you can add, delete, and update a module and the list of modules gets updated accordingly. When you select a module, its details are shown in the ModuleFormView and the corresponding list of functionalities in the FunctionalitiesListView. When you delete a module, the list of functionalities gets deleted as well.
    It should give you an idea of how to continue developing your app, at least I hope so:)

    I’m attaching a slightly modified version (more comments, etc).

    The flow of the modified app to make it easier for you to understand the changes:

    Loading XML

    1. HexaceEditorContext.onApplicationComplete
      dispatches new ServiceRequestEvent(ServiceRequestEvent.LOAD_XML);

    2. LoadXMLCommand.execute()
      configService.load(serviceRequestEvent.path);

    3. ConfigService.result
      configParser.data=ResultEvent(data).result as XML;
      configParser.mapVOsToModels

    4. ConfigService.result (after parsing)
      dispatch(new ServiceRequestEvent(ServiceRequestEvent.XML_LOADED)); triggers LoadCustomerDetailsCommand

    Sending Customer to CustomerFormMediator

    1. LoadCustomerDetailsCommand
      dispatch(new CustomerEvent(CustomerEvent.CUSTOMER_LOADED, customerModel.customer));

    2. CustomerFormMediator. onCustomerLoaded
      view.customer = e.customer;

    Requesting a list of Modules

    1. ModulesListMediator. onRegister
      dispatch(new ModuleEvent(ModuleEvent.LOAD_MODULES));

    2. LoadModulesListCommand
      moduleModel.getModulesList();

    3. ModuleModel. getModulesList()
      dispatch(new ModuleEvent(ModuleEvent.MODULE_ADDED, null, _modules));

    4. ModulesListMediator. onModuleAdded
      view.modules = event.modulesList;

    Selecting a Module from the list

    1. ModulesListView.modulesListChangeHandler
      dispatchEvent(new ModuleEvent(ModuleEvent.SELECT_MODULE, modulesList.selectedItem));
    2. ModulesListMediator
      addViewListener(ModuleEvent.SELECT_MODULE, dispatch); redispatches the event
    3. LoadModuleDetailsCommand
      moduleModel.selectModule(moduleEvent.module);
      functionalityModel.getModuleFunctionalities(moduleEvent.module.id);

    4. ModuleModel .selectModule
      dispatch(new ModuleEvent(ModuleEvent.MODULE_SELECTED, module));
      ModuleFormMediator. onModuleSelected
      view.module=event.module;

    5. FunctionalityModel. getModuleFunctionalities
      dispatch(new FunctionalityEvent(FunctionalityEvent.FUNCTIONALITIES_LIST, null, functionalitiesList));
      FunctionalitiesListMediator. onFunctionalitiesListLoaded
      view.functionalities=event.functionalitiesList;

    Adding a Module

    1. ModuleFormView. addButtonClickHandler
      new ModuleEvent(ModuleEvent.ADD_MODULE, module);
    2. ModuleFormMediator
      addViewListener(ModuleEvent.ADD_MODULE, dispatch); re-dispatches
    3. AddModuleCommand
      moduleModel.addModule(moduleEvent.module);
    4. ModuleModel. addModule
      dispatch(new ModuleEvent(ModuleEvent.MODULE_ADDED, null, _modules));
    5. ModulesListMediator. onModuleAdded
      view.modules = event.modulesList;

    Deleting a Module

    1. ModuleFormView. deleteButtonClickHandler
      new ModuleEvent(ModuleEvent.DELETE_MODULE, module);
    2. ModuleFormMediator addViewListener(ModuleEvent.DELETE_MODULE, dispatch);
    3. DeleteModuleCommand
      moduleModel.deleteModule(moduleEvent.module);
      functionalityModel.deleteFunctionality(moduleEvent.module.id);
    4. ModuleModel. deleteModule
      dispatch(new ModuleEvent(ModuleEvent.MODULE_DELETED, null, _modules));
      ModulesListMediator. onModuleDeleted
      view.modules = event.modulesList;
    5. FunctionalityModel.deleteFunctionality
      dispatch(new FunctionalityEvent(FunctionalityEvent.FUNCTIONALITY_DELETED));
      FunctionalitiesListMediator. onFunctionalitiesDeleted
      view.functionalities=null;

    Updating a Module

    1. ModuleFormView. updateButtonClickHandler
      ModuleEvent.UPDATE_MODULE, module
    2. ModuleFormMediator addViewListener(ModuleEvent.UPDATE_MODULE, dispatch); redispatches it
    3. UpdateModuleCommand
      moduleModel.updateModule(moduleEvent.module);
    4. ModuleModel. updateModule
      dispatch(new ModuleEvent(ModuleEvent.MODULE_UPDATED, null, _modules));
    5. ModulesListMediator. onModuleUpdated
      view.modules = event.modulesList;

    Saving all

    1. CustomerFormView
      dispatchEvent(new CustomerEvent(CustomerEvent.SAVE_CUSTOMER));
      addViewListener(CustomerEvent.SAVE_CUSTOMER, dispatch);
    2. SaveCustomerCommand
      ModelsToXMLParser gets data from all Models (CustomerModel, ModuleModel, FunctionalityModel,
      ModelsToXMLParser parses it into xml
      call the ConfigService or another Service class, which writes it to disk
  7. Support Staff 37 Posted by Ondina D.F. on 23 Jan, 2012 12:17 PM

    Ondina D.F.'s Avatar
  8. 38 Posted by Amnesiac on 25 Jan, 2012 06:03 PM

    Amnesiac's Avatar

    Hi,

    I've analized Your modifications and have a question:

    I was listening in functionalities list mediator for module selected and than calls functionalityModel.getModuleFunctionalities(moduleEvent.module.id) to retrieve functionalities and put them on the view.

    You moved it to LoadModuleDetailsCommand and dispatch from functionalityModel.getModuleFunctionalities -> FunctionalityEvent.FUNCTIONALITIES_LIST.

    Isn't it a little strange? Module was selected (that was a command and event) so why don't straight get all functionalities from model like I did but calls method and waits for another event.

    Every view can get functionalities (if needed) when ModuleEvent.SELECTED is dispatched.

    FunctionalitiesListMediator listening for MODIFY, REMOVE, ADD etc. events from Functionalities so it will be always up to date. FunctionalityEvent.FUNCTIONALITIES_LIST won't be used any more.

    ---- edit ----

    Or maby this should go by some LoadFunctionalitiesListCommand ? Like u made a LoadModulesListCommand??

  9. Support Staff 39 Posted by Ondina D.F. on 26 Jan, 2012 09:17 AM

    Ondina D.F.'s Avatar

    I was listening in functionalities list mediator for module selected and than calls
    functionalityModel.getModuleFunctionalities(moduleEvent.module.id)
    to retrieve functionalities and put them on the view.
    You moved it to LoadModuleDetailsCommand and dispatch from
    functionalityModel.getModuleFunctionalities ->
    FunctionalityEvent.FUNCTIONALITIES_LIST.

    Hehe, Amnesiac, I don’t know how you did that, because in your original code there were just 2 views and 2 mediators(CustomerPanelViewMediator and ModulesPanelViewMediator). I created FunctionalitiesListMediator! So I didn’t “move” anything there ;) You’d have to compare your original code with mine.

    I renamed your ModulesPanelViewMediator to ModulesListMediator (list of modules), and created ModuleFormMediator(module's details).
    You are probably referring to ModulesListMediator, which dispatches ModuleEvent.SELECT_MODULE, triggering LoadModuleDetailsCommand.

    I explained the flow in detail in my previous post.

    Isn't it a little strange? Module was selected (that was a command and event) so why don't straight get all functionalities
    from model like I did but calls method and waits for another
    event.

    I decided to use a command to access the 2 models and let the models dispatch an event, because I wanted to let you see how it would work while following the Best Practices.
    This way your models are not dependent on each other or on a certain mediator. You can access them (together or separately) from elsewhere too, if need be.
    As I already said many times in my previous posts, you are free to do it differently. If you think that injecting all the models in every mediator is better for your application, then do it. No problem. You’re right, Best Practices (loosely coupled classes, Single
    Responsibility Principle, DRY) feel a little bit strange, and if you follow them strictly you could end up with more code.

    Every view can get functionalities (if needed) when ModuleEvent.SELECTED is dispatched.
    FunctionalitiesListMediator listening for MODIFY, REMOVE, ADD
    etc. events from Functionalities so it will be always up to date.
    FunctionalityEvent.FUNCTIONALITIES_LIST won't be used any more.

    You didn’t say anything about how your application was supposed to work, what you wanted to achieve, so I just used a FunctionalitiesListView to let you see how you can load the list of functionalities, since that was one of your questions. You should try to decide what you want first, and then see what the responsibilities of each class are. You can (and should) continue to design it however you want. What I did was just an example, and I hoped that seeing the code would help you more than words.
    The other changes (besides adding commands) I made to your code were actually improving it. I don’t have the time to build a complete application for you. The modified app is not complete and not perfect. It should serve you as a starting point, though.

    Or maby this should go by some LoadFunctionalitiesListCommand ? Like u made a LoadModulesListCommand??

    Yes, you can do that, but as I said, it depends on how you want to use the list of functionalities in your application.

    I hope this long thread helped you move forward with your robotlegs app :)
    If you don’t have any other urgent issues, you can close the discussion.

  10. 40 Posted by Amnesiac on 26 Jan, 2012 09:36 AM

    Amnesiac's Avatar

    Hi again. Yes U right I didn't have functionalitiesListMediator :P i had just count of functionalities after ModuleEvent.SELECT dispatched.

    I decided to made LoadFunctionalitiesListCommand, as You said this makes models independent.

    Once again thx very much for so many posts, your time and code modifications. All that helped me.

  11. Support Staff 41 Posted by Ondina D.F. on 26 Jan, 2012 10:00 AM

    Ondina D.F.'s Avatar

    You’re welcome, Amnesiac! I’m glad I could help :)

  12. Ondina D.F. closed this discussion on 26 Jan, 2012 10:00 AM.

  13. Amnesiac re-opened this discussion on 26 Jan, 2012 05:13 PM

  14. 42 Posted by Amnesiac on 26 Jan, 2012 05:13 PM

    Amnesiac's Avatar

    Ahhh all of this is too complicated for me, every small step gives a lot of new questions :/

    1. Let say that ModuleEvent.MODULE_SELECTED occured. I want to get FunctionalitiesList so dispatch FunctionalityEvent.FUNCTIONALITIES_LIST and i get it.

    Great, but what if I want to get them for all modules at once. So i dispatch ModuleEvent.MODULE_SELECTED for every module and FunctionalityEvent.FUNCTIONALITIES_LIST and get in every module last dispatched functionalities becouse all of them was listening for FUNCTIONALITIES_LIST event.

    1. Same thing... I want a custom renderer for functionalities list. I created it and want to get the properties for every functionality... So i need to call command or get to the model. I shouldn't get them from model becouse I'm in ItemRenderer and it should not call any model methods. So I dispatch FunctionalityPropertyEvent.GET_PROPERTIES event, but every functionality item renderer called this so I don't know for which I'm getting results :(
  15. 43 Posted by Amnesiac on 27 Jan, 2012 12:49 PM

    Amnesiac's Avatar

    Ok my friends told me that I should have several VOs for example FunctionalityVO, FunctionalityWithPropertiesVO and every command should return correct VO object with or without properties.

  16. Ondina D.F. closed this discussion on 23 Feb, 2012 10:35 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