[TYPO3-mvc] Persistence of value objects

Stephan Schuler Stephan.Schuler at netlogix.de
Fri Apr 20 02:40:05 CEST 2012


Hey there.


When it comes to value objects, everything pretty much depends on what your data should be used for. In general I would say everything that is not allowed to be changed ever (!) is a candidate for being a value object.

You talked about an address as being both, a good and a bad example. And indeed it is both, depending on what a single address object is to be used for. If it's the address where I live, it's definitely no value object since I might want to move at some time, or fix a typo or whatever.
But think about an address as a part of an order. I am talking about a billing address or a shipping address. As soon as such an address is persisted together with an order, there should be no way to change it. At least not without making the order itself aware of this change.
It becomes more clear when I move to a different place and want to change my default billing address: The orders I did in the past are not allowed to change just because orders I will do in the future should use another default billing address.

This allows to two different sollutions:

Either I am not allowed to change address records as such. That's the value object approach. If I want to change my default billing address, I have to remove it from my account profile and create a new address that is bound to my account. The address objects that are connected to orders I did previously remain untouched. But this does not require my GUI to represent this 100%. I'm allowed to use input fields and an "update" button for my address, as long as the controller doesn't update the addess but replace it transparently for only the one situation the GUI shows.

Or I am allowed to change address records. But because the requirement to leave persisted orders untouched is still active, the orderFactory is in charge to create deep copies/clonse of my default address and bind the cloned address to my user profile and prospective orders.
Both approaches work quite well, but not using value objects results in multiple instances of the exactly same value pair on the persistence layer.

Of course I can always think of value objects like "they are not realy usefull since the object in terms of oop is just a smart representation of a not-so-smart scalar and so I can always use some kind of factory/transformer for it".
You might think about colors. Altough I use the "#00ffee" representation when they are stored in the database, I want to have a smart object that allowes me to access all color channels separately. Another simple example is unix timetamps which are mapped to DateTime objects by extbase. It's pretty much the same: The database does not store identity information but constructor parameters. The domain perspective is: We deal with objects, altough they only cover trivial or even scalar information.
The reason why colors and dates are no good example is the fact that everybody knows how DateTime objects are generated out of timestamp values, and everybody knows how r/g/b values are extracted out of the #00ffee representation. So nobody would even think about using a database table that contains constructor parameters as well as theyre hash value for going the very generic way of dealing with those well known value objects. The other reason why colors and time stamps are no good example is that the only constructor parameter is a very short value itself, so using a mapping table seams like overkill.

Colors are, by the way, another candidate for using value objects. Of course I can think about a t-shirt in my online shop with several colors. If I want to have color objects instead of color strings -- which is a very valid demand for almost everything that can be expressed in different ways and therefore is needed to be easy accessed by "some kind of viewHelper operation" -- colors have to be provided as objects on persistence levels. If there is no such thing like a value object, I have to use multiple color objects with individual identities. That's the only way of ensuring that changing the color of t-shirt 1 from white to light-grey does not affect all other t-shirts that are white. But having 500 products with 10 different colors results in a huge database table with trivial and duplicate information.

Another example for value objects is a price. Each price consists of an amount with tax, another amount without tax and a tax value. As long as my products are part of a shopping cart or a products list, I can always calculate most of those values in realtime. But as soon as my product is part of an order the user has signed or payed, I should realy avoid any recalculation and store each and every calculated value instead. Not using value objects but flat copies leads to huge database tables because every order creates several price objects. Not using value objects but multiple references leads to the ability to change a product price for prospective orders and affecting past orders.
The concept of value objects is the most stabel sollution for this problem. It allowes multiple references which results in lower database load and a lower object count inside my application and simply disallowes property manipulation on value objects.

The whole point is: There is no such thing like duplication and de-duplication of value objects. The only way to benefit from using value objects is to disallow every write operation on them and require themto be replaced completely instead.

And that's the point why I think that value objects are a very hard thing to bring into the TYPO3 core: The whole backend process is not meant to have "write-once" records. It might be totally valid to have writable input fields in the backend for value object properties. If it is the product configuration, I want to have a way to change the #ffffff color to #f6f6f6. But as soon as I am performing actual update operation on a value object, the TCEmain has to kick in and replace the update operation by an insert operation.

If there is a use case that requires to change all colors #ffffff to #f6f6f6 it's most probably no value object I am dealing with.


Regards,



Stephan Schuler
Web-Entwickler

Telefon: +49 (911) 539909 - 0
E-Mail: Stephan.Schuler at netlogix.de
Website: media.netlogix.de


--
netlogix GmbH & Co. KG
IT-Services | IT-Training | Media
Andernacher Stra?e 53 | 90411 N?rnberg
Telefon: +49 (911) 539909 - 0 | Fax: +49 (911) 539909 - 99
E-Mail: info at netlogix.de | Internet: http://www.netlogix.de

netlogix GmbH & Co. KG ist eingetragen am Amtsgericht N?rnberg (HRA 13338)
Pers?nlich haftende Gesellschafterin: netlogix Verwaltungs GmbH (HRB 20634)
Umsatzsteuer-Identifikationsnummer: DE 233472254
Gesch?ftsf?hrer: Stefan Buchta, Matthias Schmidt



________________________________________
Von: typo3-project-typo3v4mvc-bounces at lists.typo3.org [typo3-project-typo3v4mvc-bounces at lists.typo3.org]" im Auftrag von "Jochen Rau [jochen.rau at typo3.org]
Gesendet: Donnerstag, 19. April 2012 22:33
Bis: typo3-project-typo3v4mvc at lists.typo3.org
Betreff: Re: [TYPO3-mvc] Persistence of value objects

Hi Dennis,

On Thu, Apr 19, 2012 at 06:51:05PM +0200, Dennis Ahrens wrote:
> In the past i had problems to identify value objects at all. The
> main problem for me was the connection to the database and the way
> TYPO4 v4 handles persistence.
> "Why the hell do they have a uid? Okay, without uid -> no relation -
> makes sense... But why do i distingush than? Ah, of course, because
> they do not really have an identity - but with a uid they obviously
> have... strange..."

I had the same feeling. Now, everything makes sense to only have Objects
(=Entities) with an intrinsic identity but a clear distinction between
Concept and Representation.

> >Recently I spent some time thinking about the difference between these
> >two DDD building blocks. I came to the conclusion that there is none.
> >Eric Evans argues from a technical standpoint. The promise is, to
> >differentiate between Entities and ValueObjects will lead to a
> >performance gain and a simpler system. In fact it is quite the opposite.
> >And from a Domain perspective, we don't need to make such a distinction.
>
> Just read the part in Evans book again and i disagree that there is
> no difference in general. From the conceptual point of view the
> disjunction of both building blocks makes sense.

I still lack a good example, where it makes sense.

> But in fact we are in the world of PHP where the runtime is always
> just one request and we have to persist everything at the end of
> each request. In this environment the value object is not cheaper
> than the entity - we have to query the database for an existing
> instance. But it is also not much more expensive, it's "just" +1
> query (and if the query matches an object it's equal).

The argument made by Evans is to avoid the overhead of tracking object
duplication in memory. Now, having ValueObjects, we have to add another
query. That might save a lot of memory and processor power. But what, if
we can avoid the tracking overhead in the fist placeThat might save a
lot of memory and processor power. But what, if we can avoid the
tracking overhead in the first place??

> I currently identified my first value object that makes sense IMO -
> let me explain what and why i think that it makes sense to use a
> value object here instead of an entity. I stick near to the TYPO3
> universe...
>
> One Person have 0..n addresses. There are a few thousand instances
> that share five different addresses, because they belong to our
> university and work at one or more of our locations. In addition any
> other external person can be added with any address.
>
> If we make addresses an entity we *must* have set of all addresses
> our editors have to take care of, if we'd like to keep the number of
> redundancy addresses small.
>
> Editors can not just add a person, entering a few addresses and
> save. They have to search for existing addresses to add or create
> new. If it's modelled to reach this using IRRE we'll have a few
> thousand objects in the database that cover the same address with
> just different uids.

In fact, this is a very good example for *not* using ValueObjects.
Regarding addresses there are two domain related problems to solve:

- assigning a place to a person, and
- avoid duplication of its representation.

You could let the user select an existing place (by offering a
selection of their representations = addresses). The user can also add a
new place and enter a new representation. But you cannot solve the
problem of duplication by just declaring the address to be a
ValueObject. On the technical level it only ensures that there is only
one address with the same hash over the properties. But what if there is
a small typo? Or even 3? Or both? The problem of de-duplication has to be
solved on the UI level, not in the Domain Model.

> >So, I propose to deprecate the use of ValueObjects. In addition, we
> >should come up with some guide how to model the domain with the
> >distinction between concept and representation in mind.
> >
> >What do you think?
>
> I think that in general it makes sense to distinguish between both
> object types. I also think that it is a big task to tackle TCEMain.
> Using hooks to match the requirements of value objects is not
> reliable IMO.

Does it really make sense to add hooks, checks, database queries? I
doubt it.

> I do not follow the FLOW3 project that closely - but in general
> extbase should go into the same direction.

I cannot agree more with you. They have to be in sync especially when it comes
to fundamental principles.

Thanks for you feed-back.

-Jochen
_______________________________________________
TYPO3-project-typo3v4mvc mailing list
TYPO3-project-typo3v4mvc at lists.typo3.org
http://lists.typo3.org/cgi-bin/mailman/listinfo/typo3-project-typo3v4mvc


More information about the TYPO3-project-typo3v4mvc mailing list