22 Replies Latest reply on Jul 7, 2008 6:05 AM by Karl_Sigiscar_1971

    Flex/MVC newbie... not sure about coding practice

    fragerdaz
      Here's the idea behind the application:
      There's a database accessed by PHP (with AMFPHP) and the Flex application (using MVC pattern) displaying data from the database.

      I am fairly new to programming, so...
      What I need to know is if my code is truly designed as MVC and if I follow best practice in general.

      All comments and suggestions are appreciated. Thanks!

        • 1. Flex/MVC newbie... not sure about coding practice
          VarioPegged Level 2
          There are a few variations that you can go with here, but for me the most important thing in using a MVC pattern is to have loose coupling between the different elements. No offense, but I cringe when I see Application.application.someMethod() used in components (or anywhere else for that matter) where the whole idea of such a component is perhaps reusability.

          I also believe that the model is closely associated with the service, so it makes most sense for me to have it coupled together, perhaps even in the same class depending on complexity and such. You could of course have a separate service class that'll work hand in hand with the model. Here I just added it within the model itself, not the controller.

          Notice how the view is self-contained. It simply dispatches an event when the button is clicked. Nothing more. Then the view's dataProvider will be updated automatically when the service returns.

          Although the controller can have heaps of logic in it, it doesn't have to. I basically changed it to simply redirect, but you could choose to have it handle more of the logic. By implementing an interface, like IController, you could swap controllers and functionality at will.

          TS
          • 2. Flex/MVC newbie... not sure about coding practice
            fragerdaz Level 1
            Thanks for the reply.

            I understand why you set the dataProvider property directly in the mainApp.mxml, then use that property to populate the dataGrid in the custom component.

            I fail to understand how the dispatched event in the View is captured though...

            As for the whole IController bit, I have no clue what's going on there (lol, sorry, I am what I said I am in the title).

            Also, why do you have the Model extends EventDispatcher ?

            Last question... (although this might be what IController is intended for...)
            If I shouldn't use Application.application in my controller, how am I to change data held in the model ? How would I reference it from the controller after catching an event ?
            • 3. Flex/MVC newbie... not sure about coding practice
              VarioPegged Level 2
              Hi,

              quote:

              I fail to understand how the dispatched event in the View is captured though...

              The event listener is basically assigned inline with updateService="controller.updateService('clients')":
              <cc:Clients id="clients" ... updateService="controller.updateService('clients')"/>
              Because I've declared the updateService event within the <mx:MetaData> tag within your component, you can refer to it like I did.

              Think of a commonly used control, like Button. Its "click" event is often simply referred to inline as:
              <mx:Button id="myButton" ..... click="onClick()" /> What I did is the same way of doing it.

              quote:

              As for the whole IController bit, I have no clue what's going on there (lol, sorry, I am what I said I am in the title).

              Yeah, I wasn't quite sure whether I should throw that in there or not, but actually it's not all that tough to get. Basically I cast the controller instance to an IController, which means that I could easily swap out the current Controller class with a different controller class, as long as this new class also implements IController and has a method updateService() declared. Don't worry too much about that at this point, although you could probably read up on interfaces in general.

              quote:

              Also, why do you have the Model extends EventDispatcher ?

              Another point I should've included in my post, sorry. I'm in the habit to have certain classes extend EventDispatcher in the event (no pun intended) that I need to dispatch an event from them to the rest of the app. There are other ways to do this too, but I do it this way.

              quote:

              If I shouldn't use Application.application in my controller, how am I to change data held in the model ? How would I reference it from the controller after catching an event ?

              Not quite sure I understand fully what you mean, but your button in the view is currently set up to change the data in the model. Of course, you could easily change the data held in the model on any other type of event as well or by simply calling controller.updateService('newDataForMyExcellentApp').

              I think what I wanted to show you here is the basic setup and to avoid using Application.application ;). Like I mentioned earlier, there can be many different variations on the theme. For example, you don't have to have just a single model or controller or view, but multiple of each that cater to specific models, views, and controllers respectively.

              I hope that helps a little.

              TS
              • 4. Flex/MVC newbie... not sure about coding practice
                fragerdaz Level 1
                quote:

                Originally posted by: VarioPegged
                quote:

                If I shouldn't use Application.application in my controller, how am I to change data held in the model ? How would I reference it from the controller after catching an event ?

                Not quite sure I understand fully what you mean, but your button in the view is currently set up to change the data in the model. Of course, you could easily change the data held in the model on any other type of event as well or by simply calling controller.updateService('newDataForMyExcellentApp').

                I think what I wanted to show you here is the basic setup and to avoid using Application.application ;). Like I mentioned earlier, there can be many different variations on the theme. For example, you don't have to have just a single model or controller or view, but multiple of each that cater to specific models, views, and controllers respectively.

                I hope that helps a little.

                TS


                Hi Professor!

                That does help a bit :)
                I think I have to read up on many things Flex ;) hehe

                As for the last quoted question .. I did ask it in a complicated way, but my answer was in your mainApp.mxml modified code where "controller.model = model;". I couldn't figure out how you could use model.method() within the controller (as a result of a component's event) without using Application.application. If I understand correctly, by using controller.model = model; in the main mxml file, I ensure that the same model is referenced in the controller... right?

                One concept I can't quite get my head around is the RemoteObject in the Model. Isn't the odel supposed to hold data, period? Why shouldn't I use the controller, meant to handle events and update the model (from what I've read), to update a public variable in the model with the RemoteObject's event.result? I'm guessing the best route in a case like this is to create a seperate AS file containing my RemoteObject ? (Is that possible? advisable? How would you do it?)

                Thanks alot for all your help with this!
                -Frag
                • 5. Flex/MVC newbie... not sure about coding practice
                  VarioPegged Level 2
                  quote:

                  If I understand correctly, by using controller.model = model; in the main mxml file, I ensure that the same model is referenced in the controller... right?


                  Yes, absolutely right.

                  quote:

                  One concept I can't quite get my head around is the RemoteObject in the Model. Isn't the odel supposed to hold data, period?


                  I don't think it's set in stone that it should only hold data. I mentioned that I chose to do it this way simply because the model and service (your RemoteObject) are working hand in hand. You certainly could create a separate class that'll handle your RO calls separately and when the new data is available will update the model.

                  quote:

                  Why shouldn't I use the controller, meant to handle events and update the model (from what I've read), to update a public variable in the model with the RemoteObject's event.result?


                  You certainly could do that, but for me the controller is strictly a middle man that could orchestrate all kinds of calls and events for your app to respond to. Having the logic for connecting to your service within the controller is not something I would do. However, calling service.updateService('getSomeNewData') from the controller is definitely what I would do.

                  quote:

                  I'm guessing the best route in a case like this is to create a seperate AS file containing my RemoteObject ? (Is that possible? advisable? How would you do it?)


                  That's very possible and would be a class dealing with your service (RO). By separating it out, you gain even more reusability. From what I've shown you here, I bet you'd be able to write that class yourself. Give it a try. :)

                  Hint (or a little more than a hint): You'll simply pull out the RO logic, place it in its own class, create a model property within it and do the same as I did with the controller in the main MXML file to assign a value to that model property. Now the controller will call service.getDBList() instead of model.getDBList() and on the result event in the service you'll simply update the model from the service by calling model.acDBList = new ArrayCollection(ArrayUtil.toArray(event.result)) in the result handler.

                  TS
                  • 6. Re: Flex/MVC newbie... not sure about coding practice
                    fragerdaz Level 1
                    Hi TS,

                    I'm missing something... in your first reply with code:
                    Where does the controller "catch" the event dispatched by my view component?
                    I can see where it is dispatched in the component, but I fail to locate where it is "listened to (or) caught" in the controller.

                    Thanks as always,
                    -Frag
                    • 7. Flex/MVC newbie... not sure about coding practice
                      VarioPegged Level 2
                      Hi Frag,

                      The listener (that "catches" the event) is always a function. I assigned that listener inline to the "updateService" event in the following line:

                      <cc:Clients id="clients" ... updateService="controller.updateService('clients')"/>

                      The listener is the updateService() function (or method) in the Controller class, thus you'll refer to it as controller.updateService('clients') and that's how the connection is made for the controller to "catch" the event.

                      In this case think of the event as more of a prompt to execute controller.updateService('clients') than the controller "catching" the event, since I'm not passing any event data to the updateService() method. I could do that with a custom event, but I think that's another discussion/thread somewhere down the road.

                      TS
                      • 8. Re: Flex/MVC newbie... not sure about coding practice
                        fragerdaz Level 1
                        Ok... here goes!

                        - I've created a class called DBLink for the RemoteObject in which I instantiate my Model to send the result data back.
                        - In the Controller, I instantiate that new ro (dblink) class to call the function that retrieves db data. (Is that correct?)
                        - My Model is now as striped down as my knowledge of Interfaces (cough cough).
                        - In my main app mxml, I instantiate the model, the controller and the ro (dblink). I also set the following:
                        --- controller.model = model
                        --- controller.dblink = dblink
                        --- dblink.model = model

                        Here's the entire "new" code (I know, I know... no Interfaces... I have to read up much more on those because I simply don't grasp the concept's utility):
                        • 9. Flex/MVC newbie... not sure about coding practice
                          VarioPegged Level 2
                          Frag, it looks good!

                          Remove this in mainApp.mxml though:

                          --»public var clients:Clients = new Clients();«--

                          You're instantiating Clients via MXML: <cc:Clients ..... />

                          quote:

                          - I've created a class called DBLink for the RemoteObject in which I instantiate my Model to send the result data back.
                          - In the Controller, I instantiate that new ro (dblink) class to call the function that retrieves db data.


                          Just a minor correction on the use of the word "instantiate": you're not 'instantiating' those classes (Model and DBLink) in DBLink and Controller, you're merely declaring the variables. The instantiation happens in the main app when you create an instance with the 'new' keyword or via MXML. Then you're assigning a value to those declared variables in the main app.

                          I'd say this is a very clean and extensible little app, about as simple as a MVC app can get, but the fundamentals are all there.

                          On understanding the utility of interfaces, imagine this scenario: you've got a huge MVC app that has a ton of code and everything is working just beautifully. However, the client tells you a week before the deadline that although they love what you've done with the UI and most functionality of the application, they need to plug in their own controller logic and use a different service to update the app, etc., etc. Thank goodness you and the client decided early on to use an interface for the controller (and service too), because by you being able to seamlessly swap out your logic with theirs you actually get to make the deadline and get paid.

                          Happy coding.

                          TS
                          • 10. Re: Flex/MVC newbie... not sure about coding practice
                            VarioPegged Level 2
                            One other minor thing: I understand your use of the name DBLink for your service class, but I'd actually call the class something like RemoteObjectService or ROService. Something with the word 'service' in it. Most programmers will immediately understand what that means.

                            TS
                            • 11. Re: Flex/MVC newbie... not sure about coding practice
                              fragerdaz Level 1
                              Great! I'll make those little adjustments and continue with the rest of the app (which is basically just adding more modules like "client").

                              So, the interface is kind of like a "menu" in which you choose the method, and that menu is linked to the "kitchen" where the method is executed in whatever manner that particular restaurant makes that menu item... right? (don't laugh at the analogy :P)

                              If that's true, I implement the interface onto the actual class and when I need to instantiate my controller, I instantiate only the interface? What I don't understand is how the actual controller is referenced in the app since there's no instantiation of it, nor any reference to it in the other classes/components. It's not even mentioned in the interface...

                              Thanks for all your help! You've really put in some time and effort into this and can't thank you enough!

                              Sincerely,
                              -Frag
                              • 12. Flex/MVC newbie... not sure about coding practice
                                VarioPegged Level 2
                                quote:

                                So, the interface is kind of like a "menu" in which you choose the method, and that menu is linked to the "kitchen" where the method is executed in whatever manner that particular restaurant makes that menu item... right? (don't laugh at the analogy :P)

                                Actually a pretty good analogy ;)

                                quote:

                                If that's true, I implement the interface onto the actual class and when I need to instantiate my controller, I instantiate only the interface?

                                You don't instantiate an interface in ActionScript. When a class implements an interface, you still instantiate the class normally with the 'new' keyword. However, if you want to 'enable' the inherent benefits of that implementation, you'd want to cast the class to the interface using the 'as' keyword:

                                controller = new Controller() as IController;

                                Now if I want to swap out Controller with a DifferentController class that also implements IController, it won't break my app's functionality because DifferentController has the exact same methods and types declared as Controller (at least the ones defined in IController). IController is the 'policeman/enforcer' that makes sure of that:

                                controller = new DifferentController() as IController;

                                quote:

                                What I don't understand is how the actual controller is referenced in the app since there's no instantiation of it, nor any reference to it in the other classes/components. It's not even mentioned in the interface...

                                You did instantiate 'controller' ... but like I mentioned, you don't instantiate an interface in ActionScript.

                                quote:

                                Thanks for all your help! You've really put in some time and effort into this and can't thank you enough!


                                Not a problem whatsoever! You're very welcome.

                                TS
                                • 13. Re: Flex/MVC newbie... not sure about coding practice
                                  John Hall Level 4
                                  I've really enjoyed this discussion and learned. Thanks much for taking the time to have an in-depth conversation about MVC models.
                                  • 14. Flex/MVC newbie... not sure about coding practice
                                    fragerdaz Level 1
                                    Hi John, good to see that my ignorance is paying off to others! :) That way, TS isn't thinking just for me! hehe

                                    TS, I've made some changes in my code to lighten it (I hope), while adding more content. Am I still following the MVC guidelines and, again, is my code "up to code" ?

                                    My main worry is having a single variable in the model to provide data for my three lists. Of course, the current list will always display its own data because it's fetched according the the TabNavigator's selectedChild, but since I'm using the same variable for all three... I'm not too sure about how correct this practice really is.
                                    Also, regarding the fact that I'm passing "selectedChild.name" as an argument for my controller's method, should I rather declare a new variable in my model (ie: currentDBItem) and update that as the TabNavigator changes child?

                                    Thanks,
                                    -Frag

                                    • 15. Re: Flex/MVC newbie... not sure about coding practice
                                      cheftimo Level 2
                                      TS, I have been following this thread since it started. This is better than most tutorials I have ever taken. I read anything I see on these forums with the name 'VarioPegged', even if it is not an issue I am looking for answers to; you are truly an authority on AS and Flex.

                                      By tomorrow, I will be starting a new thread with subtopic "VarioPegged, where are you?", which I hope you will notice and will have time to respond to. It's about something very simple, but of interest to a lot of noobs like me.

                                      Thank you, TS, for all you do.

                                      Carlos
                                      • 16. Re: Flex/MVC newbie... not sure about coding practice
                                        VarioPegged Level 2
                                        Frag, Carlos, and John: It's turning into a veritable love fest!

                                        But seriously, it's a pleasure for me to be able to help in my own simple way. I'm glad if you learn from these examples. Remember though that what I'm showing here is one of many different approaches. Always remember the main reasons for the implementation of a design pattern such as MVC: extensibility, maintainability, and reuse.

                                        There is definitely a disconnect between some well-meaning flex book authors and trainers out there and the many hordes of new adopters of Flex (and Flash). There needn't be. The minute I saw Flex's capabilities, I recognized its elegance and the ease with which one can create a fairly complex app while maintaining principles of good app design. However, you have to be on your guard because this very ease that it affords us can catch unwary developers to produce an app design that'll quickly become unmanageable if it's an ambitious project.

                                        I'll remain on these forums to help in any way I can. I've been using Flex for a little over 2 years ( and loving it) and have been a developer since 1994, including Flash developer/designer since Flash 2 (circa 1997). I don't profess to know everything; there's a lot I've learned from posters like Peter Ent, Tracy, Greg, and others. What I try to bring to the forum is the knowledge that I've gained through many years of blood, sweat, and tears in the trenches, which I'll try and pass along if it'll help.

                                        TS
                                        • 17. Re: Flex/MVC newbie... not sure about coding practice
                                          John Hall Level 4
                                          Your help is quite appreciated. Since you mention 'well-meaning' book authors might lead new users astray. I've read several books on design patterns (I know, just crash and burn until you get it) but have recently heard that the Heads First Design Patterns is a great place to get the principles and concepts. Do you have any other reading/tutorial suggestions?
                                          • 18. Flex/MVC newbie... not sure about coding practice
                                            VarioPegged Level 2
                                            Frag, your app is now introducing multiple states to the model as you're finding out. In order to have states, the model will have to have some method of storing that states. Your instinct to want to have multiple variables to store the data is correct. There are many ways to do this also, for example using value objects. In your example I'm strictly using three unique variables that'll correspond with the view.

                                            Such a model now actually becomes more closely coupled with the view, since at some point you have to connect the variables and methods and states with each other. This is also why you would quite often have multiple models that cater to specific views.

                                            Unless you're foreseeing the data changing within a session, change the way you're getting the data to the creationComplete event for each ItemList to indirectly trigger a call to ROService. In ROService I added an AsyncToken that'll allow you to apply the data to a unique variable that's associated with the caller. Actually, all ResultEvents have a token property to refer to, but I've used an AsyncResponder as well. I've never used AMFPHP, so you may have to experiment a little with the logic I've added.

                                            Notice that I've changed the ActionScript-heavy ListsNav.mxml to use more MXML. For me MXML is a natural fit to code a view component. It's simpler to read and more succinct. See if you agree.

                                            Great job on creating and implementing your custom event! There are 'experienced' developers who still don't quite get custom events.

                                            TS
                                            • 19. Re: Flex/MVC newbie... not sure about coding practice
                                              VarioPegged Level 2
                                              John, I swear by Head First Design Patterns. A couple other books are ActionScript 3.0 Design Patterns and a general OOP book is Peter Elst's Object-Oriented ActionScript 3.0.

                                              A note of caution: design patterns are great and all, but learn to recognize where an app design would benefit from using design patterns versus where it's not necessary (once you have a thorough understanding of design patterns).

                                              TS
                                              • 20. Re: Flex/MVC newbie... not sure about coding practice
                                                fragerdaz Level 1
                                                During a session, the data will be updated as the user adds/updates/deletes entries in the db. Going to bed now, so I'll look at your code in detail tomorrow!

                                                Thanks !!
                                                - Frag
                                                • 21. Re: Flex/MVC newbie... not sure about coding practice
                                                  fragerdaz Level 1
                                                  quote:

                                                  Originally posted by: VarioPegged
                                                  In ROService I added an AsyncToken that'll allow you to apply the data to a unique variable that's associated with the caller. Actually, all ResultEvents have a token property to refer to, but I've used an AsyncResponder as well.


                                                  I've adapted your token idea and now use the token in the resultEvent like so:
                                                  model[event.token.message.body[0]]

                                                  I've kept a single model as the application will not get much more complicated. I'll only be adding "create, modify, delete" buttons in the ItemList.mxml component as well as a "currentItem" var in the model to keep track of which item is selected (I want to display a popup detailing the selected item selected).

                                                  Are you subsribed to this thread? If I have more questions, I wouldn't want to start a new discussion but continue where we left off.

                                                  Thanks and have a great week!
                                                  -Frag
                                                  • 22. Re: Flex/MVC newbie... not sure about coding practice
                                                    Karl_Sigiscar_1971 Level 3

                                                    I personally found Design Patterns from Addison Wesley (by the gang of four) most helpful. It is the book that started it all back in 1994 and it helps to get a grasp of the design patterns used in the Flex framework.