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: Does a Proxy need to foster a VO? Can't I just use the native AS3 XML Object?  (Read 9477 times)
sideDoor
Full Member
***
Posts: 25


View Profile Email
« on: April 14, 2010, 08:15:22 »

Ok, I've been asking questions, and I've been getting great answers, thanks so much for your time, Mr. Cliff!

Here's one about Proxies: In the case of using a Proxy to load XML, given that AS3 has pretty powerful XML capabilities with E4X, I often like to keep incoming XML data within an XML or XMLList object.  However, in PureMVC, because Proxies are suppose to steward a data object or VO, usually I see people shuttling their XML data into the VO.  But sometimes I'd kind of rather not do this...but instead just hold the loaded XML in an E4X friendly object.  Does that mean I can't be in the PureMVC club anymore?

But seriously, given that the Proxy is expecting a VO or data object, how should I proceed here?

Could I just do this within the constructor of the concrete Proxy:

:
public function MyProxy()
{
super(NAME, new XML());

// other concrete stuff
}

...and something like this in the onComplete handler of the URLLoader (PLEASE NOTE: the implicit getter for xml, which cast the inherited member, data, as an XML object ):

:
private function onComplete(e:Event):void
{
xml = new XML(e.target.data);
xml.ignoreWhitespace = true;
sendNotification(LOAD_COMPLETE, xml)
}

public function get xml():XML
{
return data as XML;
}

Would this be cool for handling XML?

Thanks!
Logged
myIP
Jr. Member
**
Posts: 11


View Profile Email
« Reply #1 on: April 15, 2010, 06:32:54 »

If other developers (if any) and yourself are comfortable and confident that the data (XML) will be conformed as expected, then I suppose its…ok.  But if the XML contains URLs for assets, how are you going to load them without violating the MVC pattern?  You wouldn’t want the View to be taking this raw data and loading assets by itself.

At any rate, its good practice not to rely on the structure of data.  If the data is not structured as expected, then your application most likely will not behave correctly.  If you deserialize your data into strong-typed value objects, then you are closer to having a more robust application that could handle data that is incorrectly structured for your application.  Creating VOs, using E4X is fairly easy to do.  When you do have fully loaded VOs (contains data from assets) Flash Player will naturally allocate more RAM.

I am hoping you or someone else can chime in on how to purge VOs.  I have an application that deserializes all data into VOs and eventually they get assets injected into them.  After the user has visited all states of the application the Flash Player allocates close to a gig of RAM.  So I obviously need to purge the assets to free up RAM and rely on the user’s browser cache to retrieve them if needed later on.  Is there a preferred pattern to do this?
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #2 on: April 16, 2010, 11:56:19 »

I see people shuttling their XML data into the VO.  But sometimes I'd kind of rather not do this...but instead just hold the loaded XML in an E4X friendly object.  Does that mean I can't be in the PureMVC club anymore?
No, rest easy, you can still be in the club. :) That's why notification body is of type object. Send whatever you want. That's none of PureMVC's business.

But from a pure OOP standpoint I advise you to avoid passing around the XML and instead to use a SmartVO[1].

When you're just passing XML from the server to the client, unless you are validating it against a formal XML schema along the way, there's no way to ensure that it contains the right data. You cannot ensure that an element that the client is planning to do a slick e4x whammy on actually exists. So you have to write all sorts of conditional code in the client to defend against this. And when you are under the gun, trying to get your app out the door, and you're mind-melding with your server-side counterpart throwing in this element dropping that parameter, etc, it rarely gets documented.

By wrapping your xml in a SmartVO, you at least encode your expectations of this XML fragment in one place, and not scattered throughout the app. So when the ad-hoc XML changes as it inevitably will, you have one place to go to adjust your client-side code.

If you notice in the SmartVO example, you're still perfectly able to wield all your e4x magic in the VO, but to the rest of your application, you are dealing with a typed object. This is good because your compiler can now catch all sorts of problems that it can't with bare XML.

If you had a Smart VO and wanted to use its XML structure or a fragment thereof to populate a tree, you could always expose a XML typed getter/setter that gets the fragment and you use that as your dataprovider.

But when you pass bare XML around you're going to end up finding e4x spread all through your app, and that's a nightmare to fix when your schema changes.

That said, there are still places where dealing with XML in the view is the right approach, though not as a value object crossing tiers. On my last project, I built a 'script composer' allowed you to create and maintain TCL scripts in either a text editor or a tree where you could drag and drop various tokens like loops and such. You could go back and forth between the tree and text representations. In the tree view, the entire TCL program was represented in an XML dataprovider. I didn't load the XML, though. I loaded TCL script and parsed it internally into XML and then back; sending TCL back to the server where it was simply saved to a file. I had to build a strict parser that was able to ensure that the XML and text were always valid TCL and in sync.

-=Cliff>

[1]See an example of a 'Smart VO' here: http://forums.puremvc.org/index.php?topic=1293.msg5973#msg5973
Logged
sideDoor
Full Member
***
Posts: 25


View Profile Email
« Reply #3 on: April 16, 2010, 06:43:43 »

Thanks,

I do understand the value of a "typed" VO, but in the case of loading XML, I was thinking of being lazy and using getters in the Proxy to return appropriate data from the structure of the XML object.  I could 'type' the data on the way out the door too, like:

public function get allProducts(productType:String):Vector.<ProductVO>
{
// TODO code:
// 1. do some e4x to get XMLList of products of productType
// 2. create Vector.<ProductVO>
// 3. loop products in XMLList
// 4. create ProductVO per iteration and push ProductVO into Vector
// 5. return Vector - OR return null if no records found, etc.
}

I really like your SmartVO example, and I guess what I'm suggesting is sort of what happening in your example, except that I'm suggesting creating the API for the XML directly on the Proxy.  But I suppose it's best to pass a VO in a notification instead of having Views directly access the API of a Proxy...

I guess my deal is that at this area of the application, in the Proxy, whether you offload your XML into a typed VO or use getters as above, it's the only place in the application that needs to know you're dealing with XML and with the particular XML structure.  I suppose if the XML changed, however, you're application could silently fail, or you'd receive null in return, prompting you to go hunting to see if the XML was properly formatted.  But wouldn't that happen anyway if you're building VOs?  As you mentioned, only schema could assist you here, no?

Thanks!
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #4 on: April 18, 2010, 04:22:15 »

I suppose if the XML changed, however, you're application could silently fail, or you'd receive null in return, prompting you to go hunting to see if the XML was properly formatted.
Just add a 'version' parameter to your object. Start with version 1 and increment for every change you make to the structure. Your SmartVO checks for the version number it is prepared to work with. Have the VO sport a 'valid' getter that will return true if (among any other checks you'd like to do) the version number equals a constant (ProductVO.VERSION) that is also incremented each time you change the structure.

In the Proxy, all you have to do is take the return from the service and pass it to the constructor of the VO. Then the Proxy checks the valid getter of the VO and if false, sends a note like INVALID_DATA and the app can then signal the user that their client software is out of date with what the server is sending.

Again this puts all the validation logic into the object that holds the data and is passed from tier to tier. This means a view component can set data on the VO and have it be validated right there. There doesn't have to be a round trip through the mediator to the proxy and back before you know something's bad.

-=Cliff>
Logged
sideDoor
Full Member
***
Posts: 25


View Profile Email
« Reply #5 on: April 20, 2010, 05:53:48 »

SmartVO indeed...Thanks, I get it!
Logged
Pages: [1]
Print