0

Note: I'm using PHP, but I think this question would be considered language agnostic. I'm also implementing "lite DDD", but I don't think that restricts the question any either.

I have a class (entity) with a lot of properties that can be set (I also have a lot of behavior on the entity, so it's not an anemic domain model).

For example, I have many string properties that look like the following:

public function setFirstName($firstName)
{
    // Removes all non-printable characters and extra spaces.
    // Also converts all "look-a-like" quotes to the standard quote character.
    $firstName = Helper::cleanName($firstName);

    if(empty($firstName)){
        throw new \Exception("first name is required");
    }

    $this->firstName = $firstName;
}

Adhereing to DRY, I see benefit in creating a "clean name" value object. But this will turn almost all of my string properties into these value objects. I also have other properties that are dates that I would turn into Carbon date value objects. In the end, it seems almost every property (that will be persisted) has become a value object. I'm concerned if I'm over-using this approach, or if there are any memory-related problems that could arrise (especially in larger collections of these entities).

How does one go about determining if a class is over-using value objects? Ie. is there a minimum standard to the amount of logic to be encapsulated to be a value object? Am I blowing up memory by making almost every property (that will be persisted) a value object? Has anyone encountered issues with a class with perhaps 30+ value objects?

prograhammer
  • 20,132
  • 13
  • 91
  • 118

1 Answers1

1

According to Mathias Verraes' excellent presentation Unbreakable Domain Models, he mentions Value Objects are the "heart and soul" of programming. So I think the ultimate answer is to not be shy when it comes to using Value Objects.

However, after thinking about the type of validation I mention in my question (cleaning characters out of these names, etc.) I have decided I can shift this to a form input handler class. It feels a little better to do some cleaning at the "application level" before getting to the domain. Of course, if I start to have any validation that requires domain logic then I should be doing that at the domain level always. And I think the Carbon dates should stay. I also have a property called "urlSafeName" (or slug) which I'm considering making a Value Object (takes a string and turns it into a more "pretty url" form).

I'm still a bit worried about VO's that hold arrays and which could be substituted for very small tables in a database. For example, a VO for a job title which comes from an array of job titles (President, CTO, Lead Developer, etc.). I'd have to be sure the array is going to stay at a manageable size, that size is of course going to be subjective though. If I have an address VO with a cityId, stateId, and countryId, then I probably want to just store them as Ids and not store all the names of those cities, states, and countries in the VO (but should be in a lookup table in the database).

prograhammer
  • 20,132
  • 13
  • 91
  • 118