tag:robotlegs.tenderapp.com,2009-10-18:/discussions/robotlegs-2/12944-how-dumb-and-fixed-should-vos-really-beRobotlegs: Discussion 2015-08-29T08:48:10Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-05-29T15:46:08Z2015-05-29T15:46:08ZHow dumb and fixed should VOs really be?<div><p>That's the best laugh I've had in awhile.<br>
I should not have been taking a sip of water while reading the
title of your post.<br>
Now, you have to buy me a new keyboard. Kidding:)</p>
<p>It is a very good question and I understand your frustration too
well!</p>
<p>What to use, Stray's or Joel's style? Both are good.<br>
But, if you feel that Joel's approach is more appealing to you, go
for it.</p>
<p>I'll try to address your concerns in more detail in the next few
days.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-06-01T16:43:14Z2015-06-02T08:45:35ZHow dumb and fixed should VOs really be?<div><blockquote>
<p>To this, I ask, why bother typing? If it just contains
properties and values, why not use a regular object? The only
advantage I see is the added structure to your code.</p>
</blockquote>
<p>There is sufficient reading material out there on the internet
and on this forum about the advantages of <strong>type
safety</strong> or strongly typed data, so I'll just mention a few
things on the subject.<br>
Some analogies :</p>
<ul>
<li>
<p>club admission: simple entry ticket vs. identity card</p>
</li>
<li>
<p>counterfeit product vs. real product</p>
</li>
<li>
<p>var i:* = "123"; vs. var counter:Number = 123;</p>
</li>
<li>
<p>as3 Object vs. VO class :</p>
</li>
</ul>
<pre>
<code>var obj:Array = [1,2,3];
someTolerantMethod(obj);//traces undefined
someNorrowMindedMethod(obj); // CTE: Implicit coercion of a value of type Array to an unrelated type SomeVO
//
var anotherObj:Object = new Object();
anotherObj.name = "robotlegs";
someTolerantMethod(anotherObj);//traces robotlegs
someNorrowMindedMethod(anotherObj);// CTE: Implicit coercion of a value of type Array to an unrelated type SomeVO
//
var someVO:SomeVO = new SomeVO();
someVO.someName = "robotlegs";
someTolerantMethod(someVO);// RTE: Property name not found on SomeVO
someNorrowMindedMethod(someVO);
//////
protected function someTolerantMethod(value:Object):void
{
trace(value.name);
}
//////
protected function someNorrowMindedMethod(value:SomeVO):void
{
//cte:Access of possibly undefined property name through a reference with static type SomeVO
trace(value.name);
//OK
trace(value.someName);
}</code>
</pre>
<p>You'll have to try this out to see the various errors.</p>
<p>A VO makes it easier to catch errors at compile time, or at
least you'll get a run time error (for example, if you pass SomeVO
to someTolerantMethod), which is really very, very good and
desirable from a programmer's perspective.<br>
someTolerantMethod will accept all kinds of "objects". If you pass
an Array in one place and an Object somewhere else, it doesn't care
(no CTEs), but the consequences might be disastrous.</p>
<p>A VO is a guarantee that you get what you expect.</p>
<p>A VO is a wrapper for properties.</p>
<p>A VO is an organized container for data. Imagine that you want
to move out of your house. You can either throw every item you
possess into a big container, or you can put your bathroom stuff
into a labeled box, BathroomVO, your kitchen stuff into another
box, KitchenVO, your books into BooksVO, and so on.</p>
<p>The advantage of using separated boxes for each group of items
is obvious, isn't it?<br>
A VO is a data carrier. It transports data from an application's
tier to another safely, and in a recognizable and identifiable
manner. An analogy - I admit, a bit far-fetched - would be a
PoliceCar, a SchoolBus, a FirefighterTruck, etc.</p>
<p>My analogies are not very good, but I hope you'll get the idea,
and I encourage you to build your own analogies with real objects.
You'd be surprised how much it helps to 'de-obfuscate' ambiguous
terms or programming concepts.</p>
<p>VO is a much abused or misused term, and has given rise to many
arguments and debates on different programming platforms.<br>
Some people talk about VOs, but they actually mean something like a
robotlegs Model. The term Model, on its turn, is also very
ambiguous..</p>
<p>Stray's definition of a VO is adhering to Martin Fowler's
definition:<br>
<a href="http://martinfowler.com/bliki/ValueObject.html">http://martinfowler.com/bliki/ValueObject.html</a></p>
<p>I think, that we all agree on the fact that an application of
any type is dealing with data.<br>
Data can be external to the application or generated by the
application, internally or through user interactions. The robotlegs
MVCS is about having specialized classes for retrieving/storing
data from/to external sources (Services), retrieving/storing data
from/to cached /in memory resources (Models), transporting data
(VOs), and presenting/receiving data to/from a user of the app
(Views), that easily communicate with each other (the classes)
through events/signals/callbacks/promises.. You can name your
classes as you wish, the fact remains, data flows in different
directions throughout your app.<br>
You'll almost always see a pattern of retrieving, storing,
manipulating, transporting, and presenting data, occurring
repeatedly.</p>
<p>How "clever" should a class be is actually equivalent to how
many roles a class should have.<br>
The robotlegs MVCS should help you identify the roles of different
classes. It should not hinder you whatsoever from designing your
classes in a way that is more appropriate to your application. The
term "best practices" should disappear from the surface of the
earth;) MVCS is just a recommendation, an example of usage, and as
such it can't cover all possible use cases and their
combinations.</p>
<p>If you think that an immutable VO is not what you need, but you
somehow want to follow those best practices in the sense of using
unambiguous names, give the class the roles you wanted it to have,
and call it SmartDataCarrier or whatever else, to differentiate it
from a VO à la carte:)</p>
<p>The different definitions of a VO have at least one thing in
common: a VO is a data carrier and it is strongly typed. Dumb VOs
might be as useful as clever ones. It really depends on the use
case. To me, more important than the IQ (ha!) of VOs is how they
fit into the overall structure of an app. If you use an immutable
VO in one place and any other variation of a VO in other places,
you may want to use meaningful names for those classes, in order to
make it clear to you (and your co-workers) what the classes are
supposed to be doing.<br>
But, as a general rule, I think, that any class that tries to be
too clever is problematic, not only a VO.</p>
<p>MVCS classes are sometimes (actually very often) making use of
helper classes, that are not part of the MVCS schema. For example,
a Service can use Parsers to translate raw data into a desired
format, Factories to build VOs or Models and so on. That means that
not every class in an application, especially in a large and
complex one, will fit exactly into the definition stated in the
MVCS. If we were very strict, a Service should
<strong>only</strong> retrieve or send data from/to an external
source. Its single responsibility should be the communication with
the external sources, right? But, another recommended practice is
to parse the data as soon as it arrives, so the Service has one
more role now, thus it makes use of a Parser. That's an example of
an acceptable deviation from the SRP.</p>
<p>I think, you can't avoid imperfections and deviations from the
so called best practices, if you want your application to work as
you desire. More often than not your intuition will help you decide
what's appropriate and what's not.</p>
<blockquote>
<p>Rather than make two calls to the database, one to update the
data, and one to rebuild a VO, we just make an update call, and on
a successful update we alter the properties of the VO
appropriately.</p>
</blockquote>
<p>That sounds good, but it is not clear to me where you intend to
update the VO and what will happen with it afterwards.</p>
<blockquote>
<p>So... what gives? Is this just a matter of preference, or need
for that matter?</p>
</blockquote>
<p>Yep.</p>
<blockquote>
<p>I would like to proceed with best practices in mind, but I'm
struggling to figure out what those are!</p>
</blockquote>
<p>I know. It's confusing. It is difficult for me to take sides. As
I said, both, Joel's and Stray's styles are ok. I prefer to use a
combination of both in my projects.<br>
But, I often recommend a flow like this:</p>
<pre>
<code>view-> event -> mediator -> event ->command->service->event
->command->model->event->mediator->view</code>
</pre>
<p>because it is what it has been mostly used in tutorials and has
been considered to be a best practice in many, many
discussions.<br>
For many use cases it is indeed the best solution, and for
beginners a 'safer' way of coding, until they find their own
style.</p>
<p>The conflicting opinions on a subject or another in this forum
only show how different projects' requirements are and how many use
cases there are, and that what's best in theory is not always best
in practice, or not always that easy to implement.</p>
<p>I'm afraid, I didn't answer all your questions, but I have to
stop now.<br>
I've already spent an hour writing this.<br>
If you want more clarifications, it would be better to have a
concrete use case as a base for the discussion.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-06-02T20:44:20Z2015-08-19T21:05:53ZHow dumb and fixed should VOs really be?<div><p>Ondina,</p>
<p>Thanks for your in-depth responses. Your knowledge and wisdom is
greatly appreciated. I am starting to wrap my head around the whole
MVCS structure. I certainly get it, still some of it just seems
counterintuitive to me. There are a few things that bother me if we
subscribe to using immutable VOs. I know you said it is not
absolute, and we can skate outside of the "best practices" of MVCS,
but maybe this can illustrate where I am struggling with the
concepts a bit more.</p>
<p>If we display a collection of our VOs in a DataGrid or DataGroup
or dropdown list an extremely useful way to keep this data up to
date is to use the Flex [Bindable] tag. If we make the VO class
[Bindable], any updates to an object in the collection propagate
immediately to the view without us having to wire any events from
the model to the mediator. But immutability renders this binding
completely useless, no?</p>
<p>Second, I'm building a value object from a sequence of server
calls. Unfortunately this particular service only allows you to get
one piece of data at a time. I want the VO to represent the state
of the data after all calls are finished. If we keep our value
object immutable, we have to construct a new version of it every
after every call. How do we keep track of the values that we've
already gotten? One solution is to track the values retrieved from
the server in a plain old object, and create an instance of the VO
at the end of all these calls. Another is to add a convenience
method to my VO similar to the <a href="https://github.com/probertson/robotlegs-examples-AddressBook/blob/master/src/org/robotlegs/examples/addressbook/model/vo/Contact.as">
Contact example</a> here. Even another is to alter my API of the
service to consolidate these calls into one asynchronous process
that resolves with the full set of values. I feel like this couples
the VO too closely to the service. What would be the most
convenient, I think, is to just give my VO setters and getters and
incrementally update after each server call, but then it is no
longer immutable.</p>
<p>I end up trying many of these things and, unhappy with the
messiness of it, throw my hands up in the air, not sure of quite
how to proceed. Perhaps I am adhering to strictly to the
architecture. I have something that works, but it doesn't seem
right to me.</p></div>dkartentag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-06-02T21:03:56Z2015-08-19T21:05:53ZHow dumb and fixed should VOs really be?<div><p>Also, it just occurred to me rereading your response. Perhaps
these issues are jobs for a model, but I don't see how to construct
the model class appropriately. There are several types of objects
which play a prominent role in my application, and I see these
first and foremost as value objects, since their properties/data
are saved, loaded, and tracked in a database.</p>
<p>Since the application can deal with potentially hundreds of each
of these object types, I have built a number of model classes that
deal with collections of these types. From what I have read in the
forums and RL best practices, model classes should be singletons,
so it makes sense for the models to deal entirely with the
collections, this way we don't have to inject things by string ID,
which would get very messy very fast. So, in my understanding, it
does not make sense to create a model class that you can use for
individual VOs. Maybe I am wrong here though, and I need to create
some sort of model that takes a VO, performs operations on it, and
returns new instances of the appropriate VO after manipulation? Or
am I muddling commands and services together here?</p></div>dkartentag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-06-02T21:58:41Z2015-06-02T21:58:41ZHow dumb and fixed should VOs really be?<div><p>I'm about to go to bed, so I'll give you a more in depth answer
tomorrow. I just wanted to let you know that your second message
about needing a model is closer to the "truth".<br>
Just do not despair. Take a deep breath, relax or go for a run.
Everything will be alright, I assure you. :)</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-06-03T16:01:28Z2015-06-03T16:01:28ZHow dumb and fixed should VOs really be?<div><p>Hi again,</p>
<p>I'm extremely sorry, but it seems that I won't be able to answer
your new questions today.<br>
I underestimated the duration of a meeting I was attending
today....and now my head is spinning making it hard for me to
concentrate on the topic of our discussion.<br>
Consider this to be the error handler of the Promise() I made
yesterday ;)</p>
<p>So, here, a new deferred.promise to answer when I get more time
- hopefully already tomorrow..<br>
Until then could you please clarify a few things:</p>
<blockquote>
<p>Second, I'm building a value object from a sequence of server
calls. Unfortunately this particular service only allows you to get
one piece of data at a time.</p>
</blockquote>
<p>Assuming that you are talking about a database table, do you
mean that you have to send a new request for a single record (table
row) at a time? . If so, do you request the next record right after
the previous one arrived, or is the next call depending on user
interactions or other conditions in your app? [many successive
requests, many responses]</p>
<p>Or, do you mean that the server is slow and you don't want to
wait until the entire data set arrives to populate your datagrid?
You want to refresh datagrid's dataprovider in succession, right?
[one request, one slow async response]</p>
<p>Regarding the question about how to manipulate VOs in a Model,
you can see that in Joel's examples that you mentioned.</p>
<p>Until I tell you more about VOs and Models, think about this
analogy:</p>
<p>The VOs could be the rows of a database table. Its properties
are the db table-columns. A collection of VOs can represent 1 to n
table-rows. The Model stores the collection, manipulates it (CRUD +
other operations) and it makes it available to the rest of the
app.</p>
<p>See you soon:)</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-06-03T19:31:22Z2015-08-19T21:05:53ZHow dumb and fixed should VOs really be?<div><p>In the second example, I'm not talking about a database table
unfortunately. It is an external service which uses NativeProcesses
and a web connection to do some validation. They have an API for
ActionScript which I have abstracted into a service in RL, but the
actual calls to their server are hardcoded in native code. I have
to retrieve a several pieces of data, but unfortunately their API
only supports getting one feature at a time (and actually restricts
from making another server call if one has not been resolved yet!).
For now, I have a loosely typed DTO (it's just an Object) that
stores data retrieved when the server responds. At the end of all
the required calls, we build a VO from the dto, and pass the VO to
the model. Any time the features are requested again, the DTO is
mutated with any new values and a new VO is constructed and passed
to the model. This seemed like the best way to achieve an immutable
VO in this case. The other solution I see is change my
getFeatures() process to return all the data in one container
(either a VO or DTO), but this seems unnecessary and tightly
coupled.</p>
<p>I completely understand that VOs should correspond to database
rows, and that is how I have constructed them thus far. I guess the
big block for me still is that I want to be able to update the VOs
tracked in my models' collections without doing a total refresh
from the database. This is huge for me because there are many user
interactions and data changes elsewhere in the model that will
update certain properties on certain VOs. So any update to an
immutable VO means creating a VO representing the new state and
replacing the old one in the collection (which you could find by
row id say) with the new one OR executing more asynchronous
database calls. This seems a bit archaic when instead I can create
a VO with bindable properties that is mutable, perform my database
update operation on it, then in the result handler of that update
call, I can update the property on the VO and have it's change
reflected across any views it is represented in, rather than
refreshing the entire collection in the model and broadcasting it
to every necessary view. Am I overestimating the expense of this
"refresh" operation vs. the single property update, and
consequently making things much more complicated for myself?</p>
<p>I can very easily see how to enforce immutability on my VOs by
constructing them in callbacks from the database and passing them
to the model, but one of the big reasons I wanted to implement a
framework like RL is to give myself as a developer more control
over tracking data in memory (the model) and wiring that properly
to the view. If I were to pass immutable VOs from the db to the
model, I almost don't even need it, can pass it straight to the
view and class out my SQL service to represent interactions with
different tables.</p>
<p>I read your discussion of VO/Model approaches here <a href="http://knowledge.robotlegs.org/discussions/questions/790-why-model-is-singleton/page/1">
http://knowledge.robotlegs.org/discussions/questions/790-why-model-...</a>
and found it very informing. I will have to reread it a bit and see
how much of that situation I can apply to my own. Once again, thank
you for debating MVCS philosophy with me. I have no one to really
discuss it with and sometimes talking out design issues, especially
with someone knowledgable as yourself, just helps you figure
everything out properly.</p></div>dkartentag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-06-04T18:42:22Z2015-06-05T14:41:28ZHow dumb and fixed should VOs really be?<div><p>First of all, thank you for your kind words!!!</p>
<p>The AddressBook example, you mentioned, was inspired by demos
used in another framework, namely PureMVC. Many of the Robotlegs
users, me included, have used puremvc before coming to Robotlegs. I
still use puremvc in some of my projects.</p>
<p>I know that you understood how VOs were used in the AdressBook
example, so please don't get offended if I'm going to repeat some
notions already known to you.</p>
<p>In the original puremvc example a Proxy communicates with an
external data source via a 'Delegate', that encapsulates the logic
for the remote call. In the added responders (result/fault) the
Proxy manipulates the data (parsing it for example) and makes it
available to other actors, either through Proxy's API or via
notifications.</p>
<p>The Mediators are allowed to retrieve a Proxy and they also can
listen to Proxy's notifications.<br>
If a View needs a list of items from a database, for example, its
Mediator is doing this:<br>
view.listOfItems = someProxy.listOfItems;, where
someProxy.listOfItems is the server call result as an array.</p>
<p>If another View is editing an item from the listOfItems, its
Mediator passes the edited values from the View as a VO to
someProxy, someProxy via its delegate sends the data to a db, and
when there is a result, it sends a notification with the current
VO, and the Mediator who registered a listener to that
notification, passes the new VO to the View.<br>
The View editing the items is using the properties of the VO as the
source for data binding for its input fields. There are 2 instances
of the VO: a currentVO and an editedVO. When an item is edited, the
View sends an editedVO (via Mediator) to the Proxy. When the Proxy
gets a result from the delegate it sends a new VO which will then
be passed to the View to replace the currentVO.</p>
<p>The logic used in this example is absolutely fine, in my
opinion. Why am I mentioning the puremvc approach?<br>
Because, for one thing, robotlegs was inspired by puremvc and some
of the examples were ported from puremvc. A lot of the concepts
used in robotlegs have been borrowed from puremvc, as well. The
main difference between the 2 resides in the use of the Model
tier.<br>
A puremvc Proxy "manipulates the data model, communicating with
remote services if need be to persist or retrieve it".<br>
In an attempt to make the separation of concerns more clear,
Robotlegs MVCS has split the Proxy into 2 classes: a Model for
manipulating and persisting the data, and a Service for
communicating with remote services. This is good, in my view. But,
it seems that many people have a hard time with this approach.
There was a lot of debate going on on the puremvc forums over
proxies' roles and the best place to retrieve them (in a command
vs. directly in a mediator) . The debate has been continued on the
robotlegs forums...with an added cause for confusion about the
difference between a Service and a Model.<br>
Based on what I've learned over the years from puremvc and
robotlegs authors and 'gurus' + all the discussions on different
forums + my own experience, I dare to say, that accessing a Model
or a Service (injected as interfaces) in a Mediator is absolutely
alright, when this kind of coupling is not producing undesirable
side effects throughout the application, like, for example,
destabilizing the state of the entire application or parts of it,
or making it hard to manage the relationships between classes. When
loose coupling is very important or when a Mediator becomes bloated
with too many responsibilities or has too many dependencies, a
Command can encapsulate all the logic for accessing the data. In
addition to loose coupling, having the code in a Command makes it
easier to change it in a single place, if need be, instead of many
places/many mediators.</p>
<p>So, if you wanted, you could have a service-promise resolver
directly in a mediator, especially if you don't need a model to
persist the data. The service parses the data into a collection of
your choice and the mediator simply passes it to the view's list
dataprovider. Done.</p>
<blockquote>
<p>This seems a bit archaic when instead I can create a VO with
bindable properties that is mutable, perform my database update
operation on it, then in the result handler of that update call, I
can update the property on the VO and have it's change reflected
across any views it is represented in, rather than refreshing the
entire collection in the model and broadcasting it to every
necessary view.</p>
</blockquote>
<p>First of all, to achieve this you'd need to operate on the same
instance of a VO. A VO would be mapped as a singleton and then
injected into all views needing it, or better into their mediators
which would pass the VO to them. BUT, this kind of binding could
lead to unpredictable results, if you don't have a mechanism in
place to synchronize the data and to update the collection of vos.
What if a view is allowed to operate on a part of the model's
collection, and another view on another chunk of data, but the VO
is always the same instance? Or, as in the AddressBook example, if
there were several views, each of them editing a different item
from the list? Maybe I don't understand what you meant. Have you
tried it out? Does it work?</p>
<blockquote>
<p>rather than refreshing the entire collection in the model and
broadcasting it to every necessary view</p>
</blockquote>
<p>So, you have the same List/DropDown/DataGrid in different views,
whose items are bindable VOs? You update the property on a VO in
the result handler of the service, and you expect the list to
reflect the changes? Maybe you need BindingUtils or an ObjectProxy
for this?</p>
<p>Unless I missed the point entirely, this scenario, even if it
worked as you wished, may be harder to manage than the
<em>archaic</em> way;)</p>
<p>In the rl AddressBook example, the VOs are allowed to update
themselves with the values of the edited VO before they are sent to
the Service or from the Service to the Model. But, that doesn't
make them more 'bindable' in the sense you've described above.</p>
<blockquote>
<p>For now, I have a loosely typed DTO (it's just an Object) that
stores data retrieved when the server responds. At the end of all
the required calls, we build a VO from the dto, and pass the VO to
the model. Any time the features are requested again, the DTO is
mutated with any new values and a new VO is constructed and passed
to the model.</p>
</blockquote>
<p>Why aren't you content with this solution? How are you passing
the VO to the model? Where are you calling the service?</p>
<blockquote>
<p>I guess the big block for me still is that I want to be able to
update the VOs tracked in my models' collections without doing a
total refresh from the database</p>
<p>So any update to an immutable VO means creating a VO
representing the new state and replacing the old one in the
collection (which you could find by row id say) with the new one OR
executing more asynchronous database calls</p>
</blockquote>
<p>You don't need to send every change to the database immediately.
That's what Models are for, to hold and manipulate the data in
memory. When you decide (on some condition or user interaction)
that the data should be sent to the db, you can send only the items
(vos) that have been changed. To know which ones have changed, you
could flag your changed vos in the collection or something like
that.<br>
If you have to send each VO to the database after it has been
updated, you probably don't need a Model at all, nor VOs for that
matter. Many people use exactly this approach:
db->service->event->mediator->view
->mediator->command->service->db or the shortcut
view->mediator->service->mediator->view.</p>
<p>To be continued...</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-06-05T11:09:47Z2015-06-05T11:09:47ZHow dumb and fixed should VOs really be?<div><p>I'm re-reading our conversation, and now I'm realizing that you
cited my dialog with Stray in your first message also because of
the bindable VO that I mentioned in there. It was just a thought I
had back then, when I was also struggling to understand the use of
concepts like VO and Model in the new robotlegs context (linguistic
or conceptual context).<br>
I've never implemented it, because I feared that it would introduce
too much complexity into my code.<br>
But, if you think that binding is a better solution to your
problems than the combination of Models, VOs and Events, by all
means, use it!</p>
<p>Look at Shaun's (the author of robotlegs) examples regarding
BindingUtils<br>
, ObjectProxy: <a href="http://stackoverflow.com/questions/13904382/trying-to-use-bindingutils-in-flash-as3-0/14060664#14060664">
http://stackoverflow.com/questions/13904382/trying-to-use-bindingut...</a></p>
<p>To be continued..</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-06-05T14:36:53Z2015-06-05T14:36:53ZHow dumb and fixed should VOs really be?<div><p>After rereading our discussion, I really don't know anymore
what's clear to you already and what's not. This makes it difficult
for me to talk about the different use cases, that you presented in
a more or less theoretical manner, without repeating myself or
without mentioning things that you already know. Sorry for
that.</p>
<ul>
<li>
<p>A VO can be used only because it is a strongly typed data
carrier and for no other reasons. Imagine a set of properties like
color, width, height, x, y, someString, etc.. that will never
change. You want to inject them into several views to render their
components in a specific way. You could use named injections for
each property or for an object or collection of your choice holding
those properties. But, a better alternative is to use a strongly
typed wrapper for those properties, that the injector can
instantiate and map it .toValue in your context-config files. Such
a VO could have getters and also other methods like for example one
that returns width+height.<br>
Such a VO is also useful when using as3-signals, but that's an
entirely other topic and I don't want to get into it.</p>
</li>
<li>
<p>Also, if a server call returns a set of properties like the ones
above, you can, but you don't have to use a VO to transport them to
different parts of your application. Any other object may be as
well suited for data transport as a VO.</p>
</li>
<li>
<p>You can keep a set of properties directly in a Model, if you so
wish. The Model can keep track of those properties without using a
VO. How you access those properties or what kind of an object you
use to transport them between classes, it's up to you.</p>
</li>
</ul>
<blockquote>
<p>Perhaps these issues are jobs for a model, but I don't see how
to construct the model class appropriately. There are several types
of objects which play a prominent role in my application, and I see
these first and foremost as value objects, since their
properties/data are saved, loaded, and tracked in a database.</p>
</blockquote>
<p>Give me an example. What do you mean by "several types of
objects" ? Do you mean something like Users, Books, Pets? If the
answer is yes, then one User would be a VO. A Users Model would be
the place to keep 1 to n users in memory.<br>
But you said: "I completely understand that VOs should correspond
to database rows....", so "several types of objects" might mean
something else.</p>
<blockquote>
<p>Since the application can deal with potentially hundreds of each
of these object types, I have built a number of model classes that
deal with collections of these types</p>
</blockquote>
<p>This means to me that you have a UsersModel, a BooksModel and a
PetsModel, etc, and<br>
UsersModel can hold a list of potentially hundreds of UserVo s.
Right?</p>
<blockquote>
<p>From what I have read in the forums and RL best practices, model
classes should be singletons, so it makes sense for the models to
deal entirely with the collections,</p>
</blockquote>
<p>I think you know by know the difference between Singleton an
mapped asSingleton.</p>
<blockquote>
<p>So, in my understanding, it does not make sense to create a
model class that you can use for individual VOs.</p>
</blockquote>
<p>I'm sticking with the Users Model. Do you mean that you'll never
need a list of users anywhere in your app, thus why having a
UsersModel (users) for a single UserVO ?<br>
Keep the properties of the User in a UserModel (user) with getters,
setter and any other methods that you need for CRUD or other
operations on the User.<br>
Of course you can call it UserVO instead of UserModel, but it would
be confusing. Now, the dilemma remains how to transport the user to
the views and from the views back to the model, right? However you
want. But, what about using a VO? ;) If a VO is your choice, then
we are back to having a UserModel and a UserVO for the purpose of
transporting the data, which is ok.</p>
<blockquote>
<p>Second, I'm building a value object from a sequence of server
calls. Unfortunately this particular service only allows you to get
one piece of data at a time. I want the VO to represent the state
of the data after all calls are finished.</p>
</blockquote>
<p>I know that you said later that this wasn't about a database
call, but just for me to understand your use case, let's say it was
a call to a strange db which would give you just one property at a
time for a User, say, call 1 gets you the userName, call 2 userAge,
call 3 userPhone and so on. When all properties are loaded, you
want to add the UserVO to a list of VOs in a UsersModel? I'm sorry
if I got it wrong.<br>
I thought futures and promises would solve exactly this kind of
problem, but since I've never used them, can't say much about it.
You said in another discussion that you used promises. Why aren't
they solving your issue?<br>
How have you solved it before using robotlegs or any other
framework?</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-06-05T17:03:09Z2015-08-19T21:05:53ZHow dumb and fixed should VOs really be?<div><blockquote>
<p>Give me an example. What do you mean by "several types of
objects" ? Do you mean something like Users, Books, Pets? If the
answer is yes, then one User would be a VO.</p>
</blockquote>
<p>You are correct. A more relevant example may be an app for
keeping track of a basketball tournament. You have things like
games, teams, rounds, scores, etc. Then we would have things like
GameVO, TeamVO, RoundVO, ScoreVO. But they're all very
interconnected. Assigning a Score to a game can advance a team to
the next round say, or change their record (wins/losses). But these
are only single properties, and the rest of the values stay the
same. On the model side, we would have a GamesModel, TeamsModel,
RoundsModel, ScoresModel all to track collections of their
respective VOs and perform operations on them.</p>
<blockquote>
<p>UsersModel can hold a list of potentially hundreds of UserVo s.
Right?</p>
</blockquote>
<p>Right.</p>
<blockquote>
<p>I think you know by know the difference between Singleton an
mapped asSingleton.</p>
</blockquote>
<p>Yes, I do. I certainly meant asSingleton.</p>
<blockquote>
<p>Of course you can call it UserVO instead of UserModel, but it
would be confusing. Now, the dilemma remains how to transport the
user to the views and from the views back to the model, right?
However you want. But, what about using a VO? ;) If a VO is your
choice, then we are back to having a UserModel and a UserVO for the
purpose of transporting the data, which is ok.</p>
</blockquote>
<p>So what I'm talking about here would be a UsersModel, which
would track the collection of users, and then a UserModel, which
would perform individual operations on a UserVO. This seems
redundant though, but if you pass the UserModel one VO, you could
operate on it and have it spit back out a new VO with the updated
values, and this doesn't break immutability. I guess UsersModel
could have a getUser method, and then any methods that would go in
this separate UserModel would just be absorbed into UsersModel and
take a UserVO as an argument. Again though, if the UserVO is
supposed to be immutable, where do we store all the data we want to
operate on without making our UsersModel too fat? Some of my VOs
have 15+ properties. Perhaps this is a sign they need to be broken
down further into more models and VOs?</p>
<p>As for the single property service calls, I'm pretty happy with
the solution I have come up with for them which I mentioned above.
The API that I have been given is event driven, so the need for a
global object/variables to track features or passing a variable
reference through a sequence of event handlers is there. I use a
promise chain to do this, but the calls to the server must be
executed in a "synchronous" async manner, meaning I cannot make
another call until the current one has been resolved. So the
process is basically getFeatureA() -> addEventListener ->
make server call -> catch server response in event listener
-> save value and resolve promise in event listener ->
getFeatureB() -> repeat etc.</p>
<p>So getFeatures() returns a chain of promises
getFeatureA().then(getFeatureB).then(...). All I was saying is it
would be nice to have this promise chain resolve with the values in
one cohesive object, but this seems impossible without a lot of
anonymous functions. I don't like tracking the properties globally
because you have to be more careful about clearing out old values,
etc., but it will do for now.</p>
<p>Thanks again for all your thoughts and advice!</p></div>dkartentag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-06-08T15:58:36Z2015-06-08T15:58:36ZHow dumb and fixed should VOs really be?<div><p>You're welcome:)</p>
<p>Now I understand, or so I think, what's giving you
headaches.</p>
<blockquote>
<p>I guess UsersModel could have a getUser method</p>
</blockquote>
<p>Of course.</p>
<blockquote>
<p>Some of my VOs have 15+ properties. Perhaps this is a sign they
need to be broken down further into more models and VOs?</p>
</blockquote>
<p>Maybe yes, maybe not. It is the same dilemma as with the
normalization of database tables. How far is far enough?<br>
It also depends on what the Models represent. Sometimes they are a
one to one representation of a db table and the user of your
application is presented with the entire set of properties.<br>
Some other time the client has to deal with results from a db join
operation. Whether you keep the data in a Model that aggregates
those join results, or you split it into more Models, it's up to
you, eventually.</p>
<p>If the 15+ properties belonged to the same object and they
should always be manipulated together, I would keep them inside a
single VO.</p>
<blockquote>
<p>...where do we store all the data we want to operate on without
making our UsersModel too fat?</p>
</blockquote>
<p>Too fat in terms of how many methods the model has, or how many
items it has to hold in the collection?<br>
Would having a UsersVO, holding the collection of UserVOs, make
your life easier? If yes, then just create a UsersVO.<br>
You don't need a separate UserModel that operates on a single
UserVO. The UserVO will always be added/removed/updated to/from/in
a collection.<br>
Perhaps you're referring to what I said in my previous post:<br>
" Do you mean that you'll never need a list of users anywhere in
your app, thus why having a UsersModel (users) for a single UserVO
? Keep the properties of the User in a UserModel (user) with
getters, setter and any other methods that you need for CRUD or
other operations on the User."<br>
But, if you know that you'll need such a list of users, having a
UserModel and a UsersModel would be redundant indeed.</p>
<p>It looks like you think that having 100+ VOs in a collection of
VOs is worse than having 100+ weakly typed objects in a
collection?<br>
Maybe you don't need VOs at all, but just a collection kept in a
bindable class (UsersVO) and operate on it. As I said, I don't want
to discourage you from using bindable models or vos, just that I'm
not proficient with this technique, thus I can't help you much.</p>
<p>Not really related to the above:<br>
Personally, I don't like to load tons of data from a server and to
keep it in client's memory. I try to <em>paginate</em> large
amounts of data, whenever possible. I would also consider
<em>caching</em> the data in a local database, sqlite for example,
to avoid too many trips to the main server(s).<br>
But maybe that's not what you want or you need.</p>
<blockquote>
<p>Then we would have things like GameVO, TeamVO, RoundVO, ScoreVO.
But they're all very interconnected. Assigning a Score to a game
can advance a team to the next round say, or change their record
(wins/losses). But these are only single properties, and the rest
of the values stay the same. On the model side, we would have a
GamesModel, TeamsModel, RoundsModel, ScoresModel all to track
collections of their respective VOs and perform operations on
them.</p>
</blockquote>
<p>This sounds to me like a datagrid with columns like this:</p>
<p>Game Name | Game Time | Team One Name | Team One Score | Team
Two Name | Team Two Score</p>
<p>I'm going to 'think out loud' about your use case, so excuse me
in advance for the following rant and the repetition of questions
you asked yourself already ;)</p>
<p>gameName and gameTime are properties of the GameVO, which has
lots of additional properties, that may be the subject of yet
another datagrid shown in another View. Same for other columns.<br>
Let's call the datagrid, GameOverview for the sake of the
discussion.<br>
The first difficulty, I see at the moment, is deciding which kind
of data provider should GameOverview utilize: column-wise or
row-wise data providers?</p>
<ul>
<li>row-wise:</li>
</ul>
<p>GameOverviewModel aggregates only the needed columns from
different collections (gameCollection, scoreCollection, etc) into a
special collection to be used only by GameOverview</p>
<ul>
<li>column-wise</li>
</ul>
<p>Instead of having a dataprovider for the entire datagrid, you
could have different dataProviders for each column.</p>
<p>But, a column in the GameOverview is actually a freestanding
collection (an array of gameNames, for example)<br>
The Model corresponding to such a datagrid (say GameOverviewModel)
should be able to update the collections representing the columns.
If the cells are editable, you want the collection, to which an
edited cell belongs, to be update as well, and each view that uses
all or parts of the collection should reflect those changes.<br>
On one hand, maybe you don't want GameOverviewModel to keep a
reference to many collections that would normally reside in
different models, GamesModel, TeamsModel, RoundsModel,
ScoresModel.<br>
On the other hand, it wouldn't make sense to assign the entire
gamesCollection to the dataprovider of the column that corresponds
to gameName, since gameName is just one property of the GameVO.<br>
Then, what if more than one cell has been modified in the
GameOverview? How to notify GameOverviewModel about the changes in
different collections? A single event with several vos as payload,
or several events with one vo? How many events will be needed to
notify all interested parties about the change of just one property
of just one VO?<br>
What if a cell of GameOverview should be updated first after
performing some calculations in a model, like the changes to the
score that you mentioned?<br>
What is better, to work with several models, GamesModel,
TeamsModel, RoundsModel, ScoresModel, or to have a
GameOverviewModel that operates on all collections used in
GameOverview? But, if GameOverviewModel is holding those
collections, what if another view needs just the gameCollection and
nothing more? Which model should take care of it? Instead of
operating on all collections, perhaps GameOverviewModel could
collaborate with the individual models in order to keep data in
sync. A Command is also a good place for orchestrating such complex
relationships and data flow.</p>
<p>...lots of possible scenarios and twice as many questions arise
all of the sudden. I don't think there is a simple solution to
this. At least I can't give you one without giving some thought to
the matter.</p>
<p>Some tips:</p>
<ul>
<li>
<p>Do you know the book Enterprise Development with Flex by Yakov
Fain and their open source Clear Toolkit? There are some very
interesting solutions to bindable collections. Look at DataForm,
DataCollection , OfflineDataCollection classes from chapter 3 for
inspiration regarding data synchronization functionality. Their
DataCollection takes care of the communication with the server as
well, which I don't really like, but if you modify the class to act
more like a model than like a model+service, it might become useful
to you.</p>
</li>
<li>
<p>Something like Parsley's Decoupled Bindings might have been the
solution you are looking for:</p>
</li>
</ul>
<p><a href="http://www.spicefactory.org/parsley/docs/3.0/manual/">http://www.spicefactory.org/parsley/docs/3.0/manual/</a>
(chapter 5)</p>
<p>But Robotlegs doesn't offer such features.</p>
<ul>
<li>Presentation Model might be a better fit than MVCS in your
case. Take a look at Joel's example:</li>
</ul>
<p><a href="http://joelhooks.com/2010/01/16/robotlegs-image-gallery-example-using-as3-signals-and-the-presentation-model/">
http://joelhooks.com/2010/01/16/robotlegs-image-gallery-example-usi...</a><br>
<a href="https://github.com/joelhooks/robotlegs-examples-ImageGalleryPM">https://github.com/joelhooks/robotlegs-examples-ImageGalleryPM</a></p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-06-10T16:09:09Z2015-08-19T21:05:54ZHow dumb and fixed should VOs really be?<div><p>Thanks for all your wisdom on this. I will look into the
Presentation model and all the other knowledge source you
suggested. I am starting to get an idea of how I want to approach
the problem, I think I am ready to dive in and let the solution
evolve organically. It may not completely obey best practices, but
if I can get something that works and stays relatively in the
framework, I will be quite happy. You can mark this as
resolved!</p></div>dkartentag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-06-11T12:18:40Z2015-06-11T12:18:40ZHow dumb and fixed should VOs really be?<div><p>You're welcome!</p>
<blockquote>
<p>I am starting to get an idea of how I want to approach the
problem, I think I am ready to dive in and let the solution evolve
organically.</p>
</blockquote>
<p>I'm glad to hear that.</p>
<blockquote>
<p>It may not completely obey best practices, but if I can get
something that works and stays relatively in the framework, I will
be quite happy.</p>
</blockquote>
<p>Don't worry too much about not obeying best practices. There is
a saying, I don't know if I can translate it well: If the frame is
too small, don't cut down the painting.</p>
<p>Anyway, since you are coding with the awareness in mind of what
might be divergent from the so called norm, you'll be able to
easily refactor your app at some point, should the need arise.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-08-26T15:55:06Z2015-08-26T15:55:08ZHow dumb and fixed should VOs really be?<div><p>After much programming, thinking, and reading, I wanted to
re-open this with a few more questions and thoughts.</p>
<p>I've come to realize that one of the big problems I was
wrestling with above, i.e. mutable vs. immutable VOs is due to a
bigger separation. After getting more a of a framework up and
running for the application, I've come to realize that I have two
cases. On the one hand, there are VOs which should be treated as
immutable and shuttled between views and models strictly as
carriers of data. On the other, there are a number of
<strong>entities</strong> which are long lived objects throughout
the app, and truly defined by their identity (in this case database
primary key) rather than their attributes. Once an entity is
created, it is used, frequently updated, and persisted throughout
the runtime until the user requests it be deleted.</p>
<p>With that in mind, how do entities fit into Robotlegs and the
MVCS structure? Should entities have a method that creates a
snapshot of their current state in a VO? Should models deal with
lists of entities?</p></div>dkartentag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-08-27T13:17:11Z2015-08-27T13:20:02ZHow dumb and fixed should VOs really be?<div><blockquote>
<p>With that in mind, how do entities fit into Robotlegs and the
MVCS structure?</p>
</blockquote>
<p>It doesn't matter if an Object with attributes is an Entity or a
Value Object, they are both belonging to the <strong>M</strong>
layer in the MVCS.<br>
Depending on its role within an application, an Object can be
defined as an Entity or a VO. Or, in other words, the same Object
can be an Entity in one scenario, and a VO under other
circumstances.</p>
<blockquote>
<p>On the other, there are a number of entities which are long
lived objects throughout the app, and truly defined by their
identity (in this case database primary key) rather than their
attributes.</p>
</blockquote>
<p>Whether there is only one unique entity instance or a set of
entity instances, you'd still need to manage their persistence
within your application. Your dilemma seems to be about where to do
that: from within the Entity itself or in a separate class like an
EntityManager or EntityContainer or whatever names those classes
have on other platforms. We would call it a Model, that would have
a property referencing multiple entities as a collection of some
sorts ( array, list, dictionary) and that would also have methods
to act upon the collection (find entities by their primary key,
update them, etc).<br>
So, in my opinion, from a persistence point of view it doesn't
matter if the objects are entities or vos as long as you're dealing
with <strong>just one</strong> object at a time. If you let them
update themselves or you use a Model to do that, you'll still be
able to send the correct data to an external database.<br>
But, if you need to keep a set (collection) of objects in memory,
you need something like a Model to manage their states and
lifecycle and to make them available to whomever needs them inside
your application.</p>
<blockquote>
<p>Should entities have a method that creates a snapshot of their
current state in a VO?</p>
</blockquote>
<p>You can do it like in the AddressBook example that we've already
discussed. Instead of sending the updated vo to the Service->DB,
you send it to the Model which will find and replace the record in
its collection and keep it in memory until you decide to send the
data to a database.</p>
<p>Or, do you mean having something like a UserEntity
<strong>and</strong> a UserVO and maybe also a UsersModel? That
would be overkill, in my opinion.</p>
<blockquote>
<p>Should models deal with lists of entities?</p>
</blockquote>
<p>Yes.</p>
<p>Conclusion: If it is more suitable for your project, create your
entities with accessors and mutators. To manage and/or keep in
memory a set of entities use a class like a Model.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/369813342015-08-29T08:48:09Z2015-08-29T08:48:09ZHow dumb and fixed should VOs really be?<div><p>I think your questions about Value Objects and Entities are
better answered by this book, that I warmly recommend reading (in
case you haven't already):<br>
Implementing Domain-Driven Design by Vaughn Vernon</p>
<p>Here an online article from the book, chapter 10 Aggregates:<br>
<a href="http://www.informit.com/articles/article.aspx?p=2020371">http://www.informit.com/articles/article.aspx?p=2020371</a></p></div>Ondina D.F.