Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: Newbie question  (Read 12405 times)
Maki
Newbie
*
Posts: 6


View Profile Email
« on: April 14, 2010, 08:30:59 »

Hi!

I'm a total newbie to PureMVC. I have done quite a bit of reading, and I'm now about ready to start using PureMVC in practice in a distance learning application where students can take courses, participate in scheduled, live lectures and take exams.

When entering the app, the user is first presented with an overview view that lists the courses to which the user is registered along with summary data about these courses.

When selecting a course the lecture view is loaded, displaying the ”current lecture”, which may be an ongoing lecture if the user has registered to it, or the next upcoming lecture.

The  lecture view consists of a slide presentation player (where the lecturer presents his slides) a video player (streaming a live feed from the lecturers web cam) and a chat where students may ask questions and participate in discussions during the lecture.

The model will look something like this:

DistantLearningApp
student
current Lectures
courses
lectures
exams

I have some problems with how to represent this in a PureMVC architecture.

1)I should be going with multicore I suppose? What would the different cores be?
2)I'm thinking each lecture should have it's own proxy. The lecture view/mediator will then be associated with the current lecture proxy for the selected course which points to a lecture proxy. Which lecture is pointed to will change with time. Does this make sense?
3)All lecture proxies will send notifications, but the  The lecture view/mediator will only be interested in notifications coming from the ”current” lecture. Is there a way to only subscribe to notifications from that particular proxy or do I have to subscribe to all lecture proxies?

Thanks,

Maki
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: April 14, 2010, 09:18:08 »

1) I should be going with multicore I suppose? What would the different cores be?
MultiCore is universally recommended, because:

1) It is better for unit testing
2) It is functionally equivalent to Standard when following best practices,
3) If your app grows and you actually need go modular, you won't have to migrate PureMVC.

However, this doesn't mean that your project needs to be modular. You might need to go modular when you have many pieces of functionality that don't need to be loaded all at once, but just when the user needs them. For instance, if your app would be many MB if it were all one project.

Why do you feel you need different cores?

2)I'm thinking each lecture should have it's own proxy. The lecture view/mediator will then be associated with the current lecture proxy for the selected course which points to a lecture proxy. Which lecture is pointed to will change with time. Does this make sense?
You can have a single proxy that manages access to the list of lectures and keeps the notion of the current item in the list. You don't necessarily have to have a separate proxy for each lecture.

3)All lecture proxies will send notifications, but the  The lecture view/mediator will only be interested in notifications coming from the ”current” lecture. Is there a way to only subscribe to notifications from that particular proxy or do I have to subscribe to all lecture proxies?
Use the third parameter to sendNotification (the type parameter) to pass the id of the lecture. Then have the mediator look at that property and decide if it needs to act on it. For instance, if the lecture id of the lecture held by the view component matches the type property of the inbound notification, then act, otherwise do nothing.

-=Cliff>
Logged
Maki
Newbie
*
Posts: 6


View Profile Email
« Reply #2 on: April 15, 2010, 06:51:37 »

Hi Cliff! Thanks for the swift response.

The model description from my last post should look like this:

DistantLearningApp
-student
     -current Lectures
-courses
     -lectures
     -exams

Why do you feel you need different cores?
I guess for the very reasons you mentioned.  :)

You can have a single proxy that manages access to the list of lectures and keeps the notion of the current item in the list. You don't necessarily have to have a separate proxy for each lecture.

Yes, I suppose if I'm only ever interested in the details of one lecture at the time (the current one), I suppose one proxy is sufficient.

How do you choose a proper "granluarity" of proxies when you have hierarchical data structures though? What should be taken into consideration? Are there any rules of thumb here?

Use the third parameter to sendNotification (the type parameter) to pass the id of the lecture. Then have the mediator look at that property and decide if it needs to act on it.

Thanks, that will do the trick of course!

One thing I find a bit awkward with  notifications (as with actionscript events in general) is that often when you're dealing with asynchronous communication you have requests and responses paired with those requests. I'm used to using the following syntax for such requests: asyncMethodName([args], callback:Function). What I like about that way of doing it is that the code is relatively easy to read. It's evident in the very call how the result of the call is handles which is not the case when you use notifications or events.

I can see how you could use notifications to emulate requests-responses by generating unique request-id's that are passed around, but to me that seems overly complicated and kind of against the purpose notifications.

/Maki
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: April 16, 2010, 12:23:55 »

Why do you feel you need different cores?
I guess for the very reasons you mentioned.  Smiley
The reasons I mentioned were why you'd use the MultiCore version instead of Standard. They weren't arguments for defining different cores within your app. You can write an app that has only one core with MultiCore. It becomes more complicated when you begin doing modular separation because you must decide how the cores will communicate and what their message protocol will be. There are added overheads in project management as well. Therefore the need to separate your code into different cores is one that is driven by many other factors than those I list with the main one being complexity. Multiple cores make the project inherently more complex, so doing it should be a choice made when you are sure that the project is of a scope that requires it.

How do you choose a proper "granluarity" of proxies when you have hierarchical data structures though? What should be taken into consideration? Are there any rules of thumb here?
Usually one proxy per complex data type, handling the list of that type is sufficient. Rarely do you need to have an instance of a Proxy for each data object, but sometimes it is a good thing. If the amount of code in that Proxy becomes inordinate because of list related and item related functionality, then you might make two separate Proxies to separate the code. One to manage the list and one to represent each instance.

often when you're dealing with asynchronous communication you have requests and responses paired with those requests. I'm used to using the following syntax for such requests: asyncMethodName([args], callback:Function).
The only problem with this is that the only actor that hears about the result is the caller. So, if you had a Mediator do this to a Proxy to tell it to fetch an object or list, then that Mediator would be the only one to hear about the return. What if three other Mediators also need to hear about it? Now it must be that first Mediator's responsibility to not only handle the return but also to notify the other Mediators. In PureMVC, we expect that responsibility to lie with the Proxy instead. This is a consequence and benefit of MVC separation. How the invocation 'looks' doesn't really enter into it so much.

If you only want the caller to act on the response, use the AsyncToken pattern to track and respond to the appropriate caller. Have your calling mediator pass its name on the proxy's method call, have the method set the name onto the AsyncToken returned by the call, and on the result, have the proxy get the name back from the token and set that as your third notification parameter. Then have the mediators who are interested in that note act if their name matches the note's type parameter.

-=Cliff>
-=Cliff>
Logged
Maki
Newbie
*
Posts: 6


View Profile Email
« Reply #4 on: April 19, 2010, 06:20:58 »

The reasons I mentioned were why you'd use the MultiCore version instead of Standard. They weren't arguments for defining different cores within your app. You can write an app that has only one core with MultiCore.

Sorry, I probably didn't have my reading glasses on. ;) I haven't really reached the point where I've taken any desicions on module separation. I may end up using a single core, but I can also see lectures becoming separate modules.

The only problem with this is that the only actor that hears about the result is the caller. So, if you had a Mediator do this to a Proxy to tell it to fetch an object or list, then that Mediator would be the only one to hear about the return. What if three other Mediators also need to hear about it? Now it must be that first Mediator's responsibility to not only handle the return but also to notify the other Mediators.

That problem is easily solved by first invoking the callback and then sending the notifications. To me we have two different concepts here, requests/responses and observers/notifications, and I don't see why the two couldn't coexist.

If you only want the caller to act on the response, use the AsyncToken pattern to track and respond to the appropriate caller. Have your calling mediator pass its name on the proxy's method call, have the method set the name onto the AsyncToken returned by the call, and on the result, have the proxy get the name back from the token and set that as your third notification parameter. Then have the mediators who are interested in that note act if their name matches the note's type parameter.

If I have multiple mediators of the same type I would have to make sure each mediator instance has a unique name, right? Is there a problem with passing a function instance instead? That way the uniqueness would be inherent in the design, if you know what I mean.

Another question: I pretty much have the domain model in place already and I now need to "hook it up" to PureMVC proxies. I'm not really sure how to go about this. I do want to keep my domain model separate from pureMVC as far as possible, but at the same time it seems so natural to I modifiy the relevant classes of my domain model (AppModel, CourseModel, LectureModel etc.) into PureMVC proxies. Or should I build a "parallel world" of proxies (e.g having a AppProxy that listen for updateCourses events so that it can in turn maintain a set of course proxies and so on.) I would really appreciate hearing your thoughts on this.

Also, please note that this is a flash (not flex) project.

Thanks,

Maki
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #5 on: April 19, 2010, 11:26:13 »

:
That problem is easily solved by first invoking the callback and then sending the notifications. If you like, its just doing double work to get the word about the return out to the interested parties if you treat the caller as a special instance.
 
If I have multiple mediators of the same type I would have to make sure each mediator instance has a unique name, right? Is there a problem with passing a function instance instead? That way the uniqueness would be inherent in the design, if you know what I mean.
You could certainly do that, but since PureMVC is available for many platforms, I advocate solutions that are effective in the platform at hand, yet portable to others. Such a solution may not play well in a language that doesn't allow passing around of functions. While your boundary classes (view and service components) will almost certainly operate differently, if your collaboration patterns remain the same then eventual migration is less difficult. At least the actors, and their roles and responsibilities and collaborations (i.e. the architecture) can remain the same.

Bottom line is, you don't want to bend over backwards to achieve portability, but if you can get it along the way by making '6 of one / half-dozen of the other' type decisions that favor portability over platform lock-in, then you're better off for it.

Platform-myopia often makes it difficult if not impossible to see such benefits. I love the Flash Platform as much as anyone, but as someone who started out in the early eighties poking hex bytes into memory addresses on 6502 based computers using a machine code monitor as a way of coding, I've seen a lot of lamentable code-rot over the years due to hitching dinghy after dinghy to one Titanic after another. I'm not predicting the demise of Flash Platform, only the eventual possibility of porting any given application to another platform.
I do want to keep my domain model separate from pureMVC as far as possible, but at the same time it seems so natural to I modifiy the relevant classes of my domain model (AppModel, CourseModel, LectureModel etc.) into PureMVC proxies.

I would define one or more VOs that represent the data structure and have the Proxies tend these. The VO can be passed freely about the tiers of the app and even be given to a view component. The Proxy acts as the keeper of the VO as the Mediator acts as the keeper of the view component. The VO could even be a Smart VO[1], that is exposing getters/setters that allow you to do validation of the data when it is set, or expose various bits of an XML structure as typed values.

-=Cliff>

[1]See an example of a 'Smart VO' here: http://forums.puremvc.org/index.php?topic=1293.msg5973#msg5973

Logged
Maki
Newbie
*
Posts: 6


View Profile Email
« Reply #6 on: April 19, 2010, 01:14:54 »

I would define one or more VOs that represent the data structure and have the Proxies tend these. The VO can be passed freely about the tiers of the app and even be given to a view component. The Proxy acts as the keeper of the VO as the Mediator acts as the keeper of the view component.

I like how that sounds, but I'm not sure I understand how you mean I should implement that. Like I said I already have an implementation of the domain model (both data structures and logic). Do you propose a parallel structure of proxies and VO's sitting alongside that model?

For instance, my domain model contains a student (instance of the StudentModel class) which in turn has a set of LectureModel instances containing quite a bit of domain logic. Should I have a an additional LectureProxy and a LectureVO? In that case what would the difference between a LectureVO and the LectureModel be?

I suppose part of why I'm not getting this is that in the examples I've seen the proxies instantiate the VO's. In my case the data structure creation should trigger proxy creation (I imagine some "parent" proxy listening to data change events in my domain model and instantiating child proxies accordingly, but that really seems a lot like double work).
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #7 on: April 21, 2010, 09:09:11 »

Your 'model' classes are the Value Objects I'm talking about. Value Objects are also known as Transfer Objects[1] and are intended for passing data between tiers.

Your domain logic for your LectureModel might either reside on that class or on the proxy that tends it, depending on various factors. This gets down to how smart to make the VO/TO/'model' class, and now smart to make the Proxy. The classic VO/TO is a pretty dumb object. But inside a client, there are pressures that push us toward a smarter VO.

The reason is that we often want a VO to reside in the view, acting as a data provider for visual controls. And when the data is edited, there are two kinds of validations we might need to make. Field level validations (ensuring that an email address is properly formed) are one, but Form level validations are sometimes pretty complex. If this field is equal to value x then these other 3 fields aren't accepted and the 4th field presents a limited set of options. Some of that logic we can't help but encode in the view component, but if we put the ultimate validation code on the VO itself, then we are assured that regardless of what tier we're on when we create or modify one of these objects, that its validity can be tested there. In the view, in a command or in a proxy. And if the VO is reused in another application, the validation goes along with it.

-=Cliff>
[1]Transfer Object Pattern http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObject.html
Logged
Maki
Newbie
*
Posts: 6


View Profile Email
« Reply #8 on: April 21, 2010, 11:29:55 »

Cliff, thank you for you patience and fantastic support!

In my case proxies would really just serve as pointers to my domain model instances (the VO's/TO's), and the VO's/TO's would contain all domain logic and data (since they already do). I like this since it keeps domain logic and data independent of PureMVC, providing maximum portability for the domain model.

What I don't like is having to add another tier (the proxies) that more or less mirrors the domain model tier, since it adds to the amount of code to write and maintain, but maybe it's worth it.

Also, in the existent domain model we have often already separated domain logic from data in very "VO like" classes (which is why I'm tempted to turn the whole model into proxies).

And I still don't see how the proxies are instantiated, since my exisiting domain model populates itself, which means the proxy does not create the VO, which has been the case in all examples I've looked at.

Maybe create a special "domain object factory" class that is used whenever a VO needs to be created that returns the VO but also creates and registers a Proxy for that VO as a sideeffect? So for instance wherever the code says new LectureModel() I'd replace that with something like DomainObjectFactory.createDomainObject("LectureModel").

On the other hand, maybe it's unneccesary to create proxies until someone actually is interested in talking to that proxy. So i could implement a getProxy() method or something like that in all my VO classes that returns a proxy for the current VO (and creates one along the way if it doesn't exist). And the only Proxy I would have from the start would be some "root" proxy that has the whole model as VO.

I'd really appreciate if you would give your thoughts on this.

Thanks again,

/Maki
« Last Edit: April 22, 2010, 04:03:05 by Maki » Logged
Maki
Newbie
*
Posts: 6


View Profile Email
« Reply #9 on: April 23, 2010, 05:24:56 »

OK, I think maybe the penny finally dropped for me... Let's see if you agree.  :)

I register a ”root” proxy (ApplicationProxy) at application startup, that takes as an argument my AppModel instance, which becomes the VO of the applicationProxy. At the same point I also register a StudentProxy, passing the AppModel's student instance to it as VO since this is a static object that we may assume will be needed by the application.

Next we have courses. The Application Proxy will listen to it's VO for course creation events. When ever that happens the Application Proxy fires a ”courseCreated” notification. If any observer is interested in the course in question, it may ask the application proxy for a proxy for that course. The application proxy will ask the facade for the course proxy, and if it doesn't exist it will register it, and then return it.

Same principle with  lectures. You can ask course proxies for lecture proxies. If the lecture proxy does not exist the course proxy registers it.

This way proxies are instantiated as the model is navigated.

Then, I'm thinking that outside of the model (e.g in the views, commands and mediators) I will use special typing of the VO's. My LectureModel Class that serves as VO for the LectureProxy has a number of public members that makes sense to expose to my model, and maybe to the LectureProxy, but that don't have any place in the PureMVC world or in my views. There, LectureModel objects are typed as ILectureVO instead. And the same principle will be used for the other Model classes that are used as VO's as well. This way I can make sure that my model classes aren't used the wrong way from the outside, while keeping the actual model implementation decoupled from the rest of the applications.

What do you think?

Thanks,

Maki
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #10 on: April 23, 2010, 09:10:55 »

Progressive navigation of the Model hierarchy in the way you describe is sensible.

I do that with XML structures often, when using the AIR XMLDatabase utility. It will pull in an XML structure and then wrap pieces of that structure with other proxies that in turn wrap their XML in Smart VOs so the rest of the app can work with the structure using typed objects. Since they are all using references to the same big structure, I can at any point (like when the app shuts down) write the big structure out to disc from the XMLDatabaseProxy subclass.

I don't know about the "ApplicationProxy" / "AppModel" though. I'd want to give them more domain-centric names.

Conceptually, the domain model should be independent of the application. Although you may not be planning it now, consider that you might eventually have mobile, desktop and web apps that all view and manipulate the same model but in different ways. So as a rule, I try to keep the Model classes not only from knowing anything about the app via references, but from even acknowledging the existence of an app, even in naming.

-=Cliff>
Logged
Pages: [1]
Print