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: Purpose of VOs  (Read 8787 times)
shanestevens
Jr. Member
**
Posts: 17


View Profile Email
« on: August 25, 2011, 05:52:48 »

Hi,

I've only used PureMVC for a couple of days, but I really like how it's constructed.  I'm mainly from a C++ background, so there are a couple of questions I have around Proxy objects and Value Objects (VOs) that I hope aren't painfully obvious to AS3 people.

Firstly, I'm not sure I fully understand the purpose of VOs.  I thought the whole idea behind Proxies was to hide the actual data representation, exposing necessary data via getter/setters.  The way I'm seeing them used is sort of an exposed key/value pair hanging off the proxy.  Are they meant to be sort of read-only objects, with the write interface being the proxy?  Or are they read/write?  If they're read AND write, this breaks encapsulation, so I'm confused.  Or are these types of VOs meant to be very simple, with pretty much non-existent Proxy objects?

Secondly, in researching PureMVC architecture, I'm seeing a lot of people have a VO full of static variables for singleton-type classes.  For example, it seems common to have an ApplicationVO where programmers access its data from anywhere using ApplicationVO.someThing.  I've even seen ApplicationVO classes with functions, that return data.  For example, I've seen one class that looks like this:

:
class ApplicationVO
{
  public static var FILESYSTEM_ROOT="some_directory/";
  public static var BASE_IMAGE_FILENAME="img_";

  public static function getPath(filename:String):String {
    return FILESYSTEM_ROOT+BASE_IMAGE_FILENAME+filename;
  }
}

I'm not sure if I'm missing the point, but shouldn't all of this be in the Proxy?

I'm seeing similar patterns in Mediators; i.e. static functions in mediators, or singleton mediators (BlahMediator.getInstance()).  Isn't this again killing loose coupling?

If the answer to all of this is simple, it's convenient, or it's because of performance, then I get it.  I'm from a console video game programming background so I understand tighter coupling for the sake of performance.  Still, why have both static Proxies AND VOs?  Why not just have a static Proxy which exposes the VO, like so:

:
class MyVO {
  public var blah:int = 0;
}

class MyProxy extends Proxy {
  private var _myVO:MyVO;
  private static var _instance:MyProxy;

  public function MyProxy() {
    _myVO = new MyVO;
    _instance = this;
  }
  public static function get instance():MyProxy {
    return _instance;
  }
  // at most expose the VO via a static in the proxy
  public static function get vo():MyVO
  {
    return _instance._myVO;
  }
}

This is how I've decided to implement singleton-type proxy objects.  Is this the right way to go, or am I missing something?

I've got more questions, but this is a good start ;)

Cheers,
Shane
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: August 25, 2011, 08:04:09 »

A value object represents a part of the Domain Model and is a data carrier that should be available across all tiers of the application. The Proxy in PureMVC is a class that has the responsibility of making the data (sometimes in the form of VOs) available to the rest of the framework actors in the app.

Don't make static methods on the Proxies to get the data; that completely defeats the purpose of the framework. The classes that should be able to access a proxy (commands, mediators and other proxies) can already retrieve a given proxy via their facade reference, allowing them to ask for its data or call methods on the proxy that manipulate or persist the data.

If you make the static methods on the proxy for accessing the data, then you (or someone else working on your app) may find yourself saying, why should I bother having a mediator retrieve the proxy (or be interested in its notifications), get the data and set it on my view component? I'll just have the view component call this static method on the proxy and cut out the middleman! This is bad. It forms a tight coupling between the view component and the framework class.

View components shouldn't know anything about the framework lest they be coupled to it and unusable in any other context. Treat view components as babies. They cry for data (dispatch an event), the mediator nanny gets a nice warm bottle of data (VOs) from the Proxy and feeds it to the view component. When the baby needs its diaper changed (modified data needs to be sent to the server), it cries and the mediator nanny takes away the data and hands it to a method on the proxy that will whisk it away to the server.

View components and Value objects are the boundaries of your application; where the rubber (framework) meets the road (UI/Domain Model). When you develop your application the first thing you should do is build the value objects that represent your model. Like the view components, they should know nothing of the framework. The view components consume the VOs, and allow the user to see and interact with the data. So they come next. They should have an implicit knowledge of the VOs, since their job is to expose and allow manipulation of them. The design of the model and the UI may influence each other, but should be pretty well developed by the time you begin fiddling with framework classes at all.

The boundaries should form the bulk of your work in a typical application. Regardless of the language or platform, this holds true. PureMVC is merely the mechanism that moves the data from the view to the model and back with possibly a little processing in between.

-=Cliff>
Logged
shanestevens
Jr. Member
**
Posts: 17


View Profile Email
« Reply #2 on: August 25, 2011, 09:28:01 »

Thanks for the explanation Cliff.

I've got a few questions off this, though.

1. In a fully decoupled environment, everything should request objects through the facade, Mediators -> Facade -> Proxies/Mediators.  Commands -> Facade -> Proxies/Mediators.  For performance reasons (games), it should be ok to at least cache the result of the facade get, right?  Something like
:
var cachedStageMediator:StageMediator in another Mediator?

2. Again, for performance, there are always going to be Singleton Mediators/Proxies.  For instance, the StageMediator in my system is responsible for emitting resize messages, and also contains our window/viewport system.  It's general and won't be changed, certainly within the same project lifecycle, so it could make sense to expose a public static singleton accessor instance().

3. Likewise, singleton VOs seem like they could be ok with static accessors/variables, especially given they aren't necessarily connected to an MVC Proxy.

4. If I go the 'pure' path, and design VOs first, followed by the View Components that display them, before building the plumbing into Mediators/Proxies, accessing everything via the facade, what objects do you typically build VOs for?  i.e. Do you just build VOs for marshalling data around between the various MVC classes, or do AS3 programmers tend to use them in place of traditional data structures defined as classes?

I guess what I'm really trying to work out, is do you tend to use the MVC as scaffolding to link up the views with their data, with the commands acting as a bit of glue, whilst leaving the rest of the app/game to manage their systems internally.  i.e. The whole app/game could be in a single Mediator GameMediator, with custom drawing etc, with traditional data structures kept as an internal detail, with the rest of the HUD, or title screen, or high scores etc as their own Mediators.

Cheers,
Shane
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: August 26, 2011, 08:07:39 »

For performance reasons (games), it should be ok to at least cache the result of the facade get, right?
Yes, for Proxies. You'll see this in many of the demos. Buy you should try to avoid retrieving Mediators and acting on them and instead communicate with them via notification. This is a looser coupling, and what we're trying to achieve with the framework.

Again, for performance, there are always going to be Singleton Mediators/Proxies.  For instance, the StageMediator in my system is responsible for emitting resize messages, and also contains our window/viewport system.  It's general and won't be changed, certainly within the same project lifecycle, so it could make sense to expose a public static singleton accessor instance().
Don't use Singletons. Yes the framework uses them, but differently. They are used internally, and their access is by convention limited to the Proxy, Command and Mediator actors within the system, which actually never refer to the Singletons statically, but instead are imbued with a reference to the Facade through which the things they need are provided. On the matter of other Singleton usage, I stand with most of the OOP programming community in saying that they usually lead to nothing but Big Balls of Mud[1]. The time to retrieve a Proxy via the Facade from any Command, Mediator or Proxy (the only classes that should be retrieving a Proxy) is no less performant than calling a static instance method. And it's not like you're going to find yourself compute-bound retrieving the same Proxy 1000 times per second. Performance is not a justification for the use of Singletons to augment the framework.

what do you typically build VOs for?  i.e. Do you just build VOs for marshalling data around between the various MVC classes, or do AS3 programmers tend to use them in place of traditional data structures defined as classes?
Both. Value Objects are classes whose instances represent data from the Domain Model. They typically have typed properties and are used to present data to the View or to move new or modified data back to the Model.

Likewise, singleton VOs seem like they could be ok with static accessors/variables, especially given they aren't necessarily connected to an MVC Proxy.
Again, this would totally defeat the purpose of the framework. Singletons are one of the chief ways of creating spaghetti code. Once you can access something from anywhere, you start writing code everywhere to access it. Since it's a handy place, more and more things start being put on that class, which becomes a monolithic God Object[2]. Like a black hole, it eventually couples every class in the system to it, making it impossible to reuse any object without taking the God Object and lots of irrelevant stuff along with it.

[1] Big Ball of Mud - http://www.laputan.org/mud/mud.html#Abstract
[2] God Object - http://en.wikipedia.org/wiki/God_object
Logged
shanestevens
Jr. Member
**
Posts: 17


View Profile Email
« Reply #4 on: August 26, 2011, 04:08:15 »

Anybody would think you don't like singletons! ;)

Ok, point taken, and to be honest I do like the purity of the Facade as the only singleton.

There are really a lot of examples floating around in the wild that use static accessors to death in the data (proxy/VO) layer, so finding a consistent usage pattern can be somewhat frustrating.

Thanks for your responses.

Cheers,
Shane
Logged
jpwrunyan
Sr. Member
****
Posts: 84


View Profile WWW Email
« Reply #5 on: September 05, 2011, 11:55:12 »

Ok, point taken, and to be honest I do like the purity of the Facade as the only singleton.

Allow me to be pedantic and repeat/emphasize something Cliff said: the Facade is not the only singleton.  Controller, Model, and View are also singletons.  It's just that we access them via Facade.  This knowledge has been helpful for me.

Singleton proxies have been the bane of my existence.  But God Object is a misnomer.  Malignant Cancer Object is more accurate (with the added bonus of being a TLA).
Logged
Pages: [1]
Print