Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine 2 Value Objects

I have been implementing value objects as custom DBAL types in Doctrine 2 and it's been working OK. However I have been wondering if this is the best way. I've thought about using the Post Load listener to instantiate the Value Objects. Also instantiating them through Entity accessors when requested, the advantage with the latter would be that I would not instantiate more objects than I need.

My question is: which method is best? Or is there a better way to do it? Are there any gotchas or unreasonable performance hits with the above?

like image 602
John Avatar asked Dec 09 '11 03:12

John


People also ask

What is doctrine mapping?

As an example, the Doctrine Mapping Type string defines the mapping from a PHP string to a SQL VARCHAR (or VARCHAR2 etc. depending on the RDBMS brand). Here is a quick overview of the built-in mapping types: string : Type that maps a SQL VARCHAR to a PHP string. integer : Type that maps a SQL INT to a PHP integer.

What is a repository doctrine?

A repository in a term used by many ORMs (Object Relational Mappers), doctrine is just one of these. It means the place where our data can be accessed from, a repository of data. This is to distinguish it from a database as a repository does not care how its data is stored.

What is doctrine persist?

The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share. You can use these interfaces and abstract classes to build your own mapper if you don't want to use the full data mappers provided by Doctrine.


1 Answers

IMHO, both approaches are equally valuable, while waiting for native support for value objects.

I personally favor the second approach (instantiating them through accessors when requested) for two reasons:

  • As you mentioned, it offers better performance as the conversion is only done when needed;
  • It decouples your application from Doctrine dependency: you're writing less code that is Doctrine-specific.

An example of this approach:

class User
{
    protected $street;
    protected $city;
    protected $country;

    public function setAddress(Address $address)
    {
        $this->street  = $address->getStreet();
        $this->city    = $address->getCity();
        $this->country = $address->getCountry();
    }

    public function getAddress()
    {
        return new Address(
            $this->street,
            $this->city,
            $this->country
        );
    }
}

This code will be fairly easy to refactor when Doctrine will offer native VO support.

About custom mapping types, I do use them as well, for single-field VO (Decimal, Point, Polygon, ...) but would tend to reserve them for general-purpose, reusable types that can be used across multiple projects, not for project-specific single-field VO where I would favor the approach above.

like image 123
BenMorel Avatar answered Oct 20 '22 04:10

BenMorel