| Ultrashock Forums
App: MVC Gallery |
Member Blogs | ||
![]() |
||||
| Search this Thread | Thread Tools | Display Modes |
| <<<3456> | Page 5 of 6 |
5 Blog Entries
|
2007-10-01
#161 |
||
|
Okay
|
|
5 Blog Entries
|
2007-10-01
#162 |
||
|
This will take a while...
|
|
5 Blog Entries
|
2007-10-01
#163 |
||
|
Are you ready? Grab a coffee and a snack if you want.
|
|
5 Blog Entries
|
2007-10-01
#164 |
||
|
Last edited by Codemonkey : 2007-10-07 at 03:24.
Here goes...
Originally posted by sentinels That may be the case with Cairngorm, but you don't have to have command objects with MVC and you are describing one with a passive model as well, which is not what the gallery demo is about (for basics). You're still right tho.err... any MVC i've ever worked with never had the controller updating anything. all the controller would do is handle requests from the view, create command objects to pass to a service, and potentially dispatch an event to inform any listening view(s) that the model has been updated once the service has returned a result. the delegate or command should be the object updating the model and informing the controller that the model has been updated.
Originally posted by Nutrox That's actually a pretty cool approach. I had to think about the PlayerEngine being an observer for a second, but I think it would work pretty well. It would not actually be a view, just an observer sitting next to the views, which is cool.I have been thinking about how a music player with a GUI would fit into MVC, and I was thinking about something like this: PlayerModel (observable) - Contains the player's state, volume/pan, and play list data etc. PlayerEngine (observer) - Contains and manages the actual Sound object. PlayerUI (observer/view) - Contains and manages the GUI. PlayerController (controller) - Handles the interaction feedback from PlayerUI and updates PlayerModel via command objects.
Originally posted by Nutrox A view generally has only one controller, but this does not have to be the case. It also depends on how the controller is set up.Oh, one more thing. Can a view only have one controller assigned to it For example, the controller might just be an observer on all the view's controls and handle the events directly. Then you have a 1-on-1 relationship. This is a nested observer application where the controller acts as observer to catch interaction at the lowest level, or at least at the level where events are broadcast by the components/controls in the view. Another setup is where the view acts as observer to its own components' events and filters which events are delegated to the controller and which events are handled by the views which then possibly results in some call to the controller. Here there does not have to be a 1-on-1 relationship, because the view can decide which controller to call upon for which event or action. Keep in mind though that the view has no power over the controller; it doesn't create or remove a controller for itself. In classic MVC a view has a reference to a controller but only through an interface, which means the view won't know which implementation of the controller it has. You could for example replace a NormalGameController with a PausedGameController where most implemented methods actually don't do anything with the model (if the pause logic is not contained within the model itself but managed by the controller in the first place). That said, a view might well have multiple controller references of interface types that all have their own responsibilities towards the model. There's no reason why you need only one controller which actually only receives very low cohesion.
Originally posted by Nutrox A view can have multiple models from which they can draw information and receive updates from, because in its heart the model-view relationship is that of Observer. Is it advisable? Nothing against it and no convention here that I know of.or can a view watch multiple models? One thing to consider though is the fact that multiple models are not tailored with knowledge of each other; they can demand different kinds of treatment to get information from, through updates and sometimes you want to make sure they update the shared view coherently and consistently the same way. In addition, both models may overlap in the data being provided and you need to apply logic to sort out what information you want to keep from an update. In such a case, I would consider creating an 'adapter model' (arbitrary term) that receives both kinds of updates and creates neat little filtered update packages and sends these to its own views (the real views). So: "model 1 or 2 sends update"->"adapter model transforms and also sends update"->"views receive consistent updates from intermediate model" This is only necessary in more extreme cases where you have existing views and models and you need to add a model or couple views to other models. In Enterprise environments this is an entirely possible scenario though.
Originally posted by Nutrox Not at all, it's actually a very descent approach and in fact you'll be proud to hear this is actually a design pattern of its own I was thinking that instead of having getters/setters hardwired in a View you could create a special object which ( a ) encapsulates collections of related getters/setter, and ( b ) talks to the Controller in that same way a View does. That way the Model would still hold all of the data and the Controller would still be the only thing that updates the Model. Is this making any sense, or am I completely crazy?
![]() Facade (more info) Though the intention of the Facade pattern is to simplify some subsystem(s) into a simplified interface (access point), your intention isn't all that different: you simplify the system by collecting all setters/getters in one easily accessibly place (style). You simply added a set / get mechanism on top if it which is unique to flash. It sounds perfectly fine to me. Here's another scenario: Have the controller contain all these properties and setters/getters instead of the style object, and the MVC becomes a variation on the Supervising Controller/Presenter pattern ![]()
Originally posted by Nutrox It's not clear to me what the best place is to actually wire the models with views with controllers (the binding phase) and whether this is a one time event or if this can be dynamically assigned variably in runtime.@CM Another question regarding the way you have coded the MVC classes/interfaces: In your implementation of MVC you have things setup so that the View can only have one Model and one Controller added to it. In that situation, would it not be better to a getter/setter for the model and control references instead of using getModel() setModel() etc? That said, I'm not sure if it's a good idea to give views the power to fetch their own preferred model. That's because a view is 'plugged' into a model and after that only has a one-way line of communication. Having getters for models would give the view a different kind of role where they would already need some logic to determine which model to get (depending on how complex the environment is; multiple models and stuff). To actually answer your question, you are right in assuming getModel() and setModel() are rudimentary and only applicable to a single model. As we determined earlier you can have multiple models (and controllers for that model) and they both should be able to be obtained by a view. So specific getters for all models? Then you would have getSoundModel(), getGameModel(), getStyleController() and so on. Or you could dump em in an associative array and fetch them by name (or some constant). What I certainly wouldn't do without good reason is make the model a singleton. Models don't inherently have to be singletons, you could for example have multiple racecars on a track that are all encapsulated MVC-based components.
Originally posted by Nutrox Not from Java, but from Moock's implementation of the Clock example in his book. In his version a controller can have only one view and model. and his observer version can only have one observable.If you were allowing multiple Models to be added to a View then the use of addModel() removeModel() methods would obviously make sense, but I don't see the point of using getModel() setModel() when only one Model can be added to the View. Is the use of getModel() and setModel() just something that has sneaked across from Java, or is that the 'normal' way to do things in MVC? This makes sense for the simplistic academic exercise, but if you need to move on to more realistic real life applications of the MVC pattern youŽll often find yourself needing just a bit more in various places. And as you are now finding out, MVC allows for a multitude of tweaking.
Originally posted by Nutrox Looking good, but in the IController, I wouldn't make the model and view properties public. For that, I would use an abstract class to hide it away a little bit and make it visible only to subclasses.How is this looking... 0-9-4.zip The classes and interfaces don't have comments at the moment, but I have included documentation for them for quick viewing. It is based heavily on the framework Codemonkey uploaded. The next step will be trying to base an MP3 player on that framework. I will upload that when it is working. On a side node, I like how you used identifiers for the Commands in the controller. One way of implementing the command objects then would be to construct/initialize them with a controller which they could register themselves with (in the model?). The same reference to the controller can also be used to reuse other commands and so create a chain of commands without the commands themselves know about it (the controller creates those commands after all). - Cm. PS. as long as you think my answers are coherent enough to follow, ask away
|
|
1 Blog Entries
13 Creative Assets
|
2007-10-01
#165 |
||
|
Last edited by Nutrox : 2007-10-01 at 14:50.
Great feedback as usual mate. I will check out that supervising controller stuff, although I've only just got my head around the whole MVC and Command patterns so I might leave it for a while. ![]() Regarding the IController interface, I do understand what you are saying there. My initial thought was that any controller implementing the interface would (afaik) need to allow public access to the to model and view properties anyway. I take it that isn't always the case then? Oh, and I will throw a ModelAdaptor class into that code soon. ![]() |
|
1 Blog Entries
13 Creative Assets
|
2007-10-01
#166 |
||
|
Originally posted by Codemonkey The way that I intend to register the commands is within the controller. Here is an example:... On a side node, I like how you used identifiers for the Commands in the controller. One way of implementing the command objects then would be to construct/initialize them with a controller which they could register themselves with (in the model?). ActionScript Code:
ActionScript Code:
|
|
1 Blog Entries
13 Creative Assets
|
2007-10-01
#167 |
||
|
Last edited by Nutrox : 2007-10-01 at 18:46.
Here is an update... 0-9-5.zip The methods sendError() and sendResult() have been added to the IService interface. You can see how they are used in the Service.as class if you are curious, but it a nutshell, they are helper methods. I have also added a new interface, IFacade, and a new class, Facade. Facade is an observer and I decided that it can only have one Model and one Controller registered to it, unlike a View which can have multiple Models. FYI: A Facade would be used for something like component style.* properties as we discussed up there^ somewhere. ![]() Edit: 0-9-5 has been uploaded again and now contains DataObject, the existing interfaces and classes have been updated accordingly. |
|
1 Blog Entries
13 Creative Assets
|
2007-10-01
#168 |
||
|
Would it be better to create an IInfoData interface or InfoData base class, and use that instead of an anonymous Object? So instead of this: ActionScript Code:
ActionScript Code:
|
|
1 Blog Entries
|
2007-10-01
#169 |
||
|
i usually use value objects to pass data back and forth between my classes.
|
|
1 Blog Entries
13 Creative Assets
|
2007-10-01
#170 |
||
|
Originally posted by sentinels That does seem like a better thing to do IMO, Object is just too generic I think. I have created an abstract DataObject base class (aka value object).
i usually use value objects to pass data back and forth between my classes. |
|
1 Blog Entries
13 Creative Assets
|
2007-10-01
#171 |
||
|
@CM I'm having a bit of trouble creating a ModelAdaptor class. I understand the theory, but I'm not sure how it would be constructed. Any chance of a quick example? Also, would the View need addAdaptor() and removeAdaptor() methods now? |
|
1 Blog Entries
|
2007-10-01
#172 |
||
|
i don't think you'd need an abstract class for value objects. since these objects are generally specific to the data, you would normally pass the specific value object you need/request.
|
|
5 Blog Entries
|
2007-10-01
#173 |
||
|
Originally posted by Nutrox Not sure about that, but it would mean a view is able to obtain a reference to the model through its controller... which it shouldn't be allowed to do (breaking the loose coupling that way).Regarding the IController interface, I do understand what you are saying there. My initial thought was that any controller implementing the interface would (afaik) need to allow public access to the to model and view properties anyway. I take it that isn't always the case then?
Originally posted by Nutrox It's not really an adapter to the view, rather just a model it relies on. The views also don't know there are actually other [multiple] models underneath it.Also, would the View need addAdaptor() and removeAdaptor() methods now? So to the views it is still addModel and removeModel, except it's a different model that happens to adapt other models to a certain interface (the interface being expressed through updates). --- I'll get back to you about the rest tonight. |
|
5 Blog Entries
|
2007-10-02
#174 |
||
|
Originally posted by Nutrox Yep, I've had the same issue with this and introduced a common interface for infoobjects. The problem here though is that if you do have multiple models, all their update notifications need to extend/implement that superclass, which means an interface can't be specific to a model or a model's update.Would it be better to create an IInfoData interface or InfoData base class, and use that instead of an anonymous Object? So instead of this: [...] You would have this: [...] Using Object just feels a bit too loose to me, unless of course the data should be able to be besent as XML, Array, or anything else. It's a good way to 'mark' an update object with a marker interface so that only objects with that interface are send in an update, but that's about it. There are no common functions other than metadata like 'update type' or statistical data like 'updates so far'. You'll always need to cast it to a specific type of infoobject. You can do that per type of update or you can define a generic update per model that contains all the properties of the model which are filled as necessary for the specific update (ie. only fill in currentImage if the update contains type UPDATE_LOADING_IMAGE). The updates have always been a bit problematic, because you have a one-to-many relationship between a model its updates, and a view needs to distinguish between the various types of updates. So far I've done that by having all updates extend a baseclass that contains a bitflag with the update meta information (type of update). |
|
1 Blog Entries
13 Creative Assets
|
2007-10-02
#175 |
||
|
Originally posted by Codemonkey I'm confused now. Not sure about that, but it would mean a view is able to obtain a reference to the model through its controller... which it shouldn't be allowed to do (breaking the loose coupling that way). ![]() In your View interface you have public getModel, setModel, getControllers, and setController methods. In your Controller interface you have public getModel, setModel, getView, and setView methods. Wouldn't those methods be just as accessible as getters/setters? Your View is still able to get a reference to the Model from the reference passed to it, or from the Controller (getModel is public). The only way I can see around that would be to remove the get/set Model methods from the View, and remove the get/set View methods from the Controller, then register like this: Code:
model.registerView( view ) view.registerController( controller ) controller.registerModel( model ) That way the View cannot access it's model at all until/unless a model reference is passed to it via the update() method. In the same way, the Controller would not be able to access the View unless a reference was passed to it via it's executeCommand() method. |
|
5 Blog Entries
|
2007-10-02
#176 |
||
|
Yup, these days I would probably do it like that as well. I just reused to view interface from Moock's book at the time. Today, I wouldn't apply the same approach.
|
|
1 Blog Entries
|
2007-10-02
#177 |
||
|
wha? that makes no sense to me. a model should not care about which view and/or controller is accessing it. the model should just be a class that receives results from a service, manipulates the data for the application, stores it and provides hooks (getters) to access it. the view should be notified when a result has been returned from a request (through the controller), then goes to the model to fetch the necessary data. all the controller acts as is a means for the view to send requests to and receives notification on service results. don't know why you would need any of the above methods, except maybe registerController, but even then i'd rather instantiate the controller directly and pass it a reference to my view. either that, or use a central event framework (like cairngorm does) and use specific events to register to specific requests.
|
|
5 Blog Entries
|
2007-10-02
#178 |
||
|
I don't understand why you hammer on these services so much, those have nothing to do with MVC itself, which is what this thread is about. The controller in this situation acts as liason between the view and the model to pass on requests. The model then provides updates to the views.
Originally posted by sentinels Firstpart: I don't know why you think the model knows about its views, but the method is there to adhere to the Observer pattern. The views are listeners here.wha? that makes no sense to me. a model should not care about which view and/or controller is accessing it. [..] don't know why you would need any of the above methods, except maybe registerController, but even then i'd rather instantiate the controller directly and pass it a reference to my view. Second part: Isn't that exactly what is going on? |
|
1 Blog Entries
13 Creative Assets
|
2007-10-02
#179 |
||
|
I have to say that I don't see a problem doing things this way either. Even though observers are being added to the model (observable) the model doesn't care what observers are added to it. When the model is updated it just rolls through it's list of observers and invokes the update() method in each one. The view doesn't access the model directly, all update info is passed to the update() method when it is invoked by the model. That gives us the M->V (or Observer) pattern. The same goes for the controller really. View doesn't care what controller is added to it, all View cares about is being able to invoked the controller's executeCommand() method which in turn does what is needed to update the model (using commands/services/whatever). That is how I'm seeing things from a noob perspective anyway.
|
|




5 Blog Entries


13 Creative Assets