Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD Factory Entity Value Object

I have been increasingly adopting DDD / Onion Architecture in my current project. One of the many things I am still unclear about is how much encapsulation should there be. Easier explained with a concrete example.

Example

namespace MyProject.Model
{
    public class ComplexEntity
    {
        private int _id;
        public int Id { get {return _id;} }
        public ValueObjectA ValueA {get; set;}
        public bool IsBool {get; set;}
        public ComplexEntity(ValueObjectA a, bool isBool)
        {
            // Do some validation first
            ValueA = a;
            ValueB = b;
            IsBool = isBool;
        }
    }

    public class ValueObjectA
    {
        public bool IsBoolA {get; private set;}
        public bool IsBoolB {get; private set;}
        public ValueObjectA(bool a, bool b)
        {
            IsBoolA = a;
            IsBoolB = b;
        }
    }

    public Interface IComplextEntityFactory
    {
        // Option 1
        ComplexEntity Create(
            ValueObjectA a,
            bool IsBool);

        // Option 2
        ComplexEntity Create(
            bool valueABool a,
            bool valueBBool b,
            bool isBool);
    }
}

Question

For the factory of an entity, do you,

  1. Expect the caller to construct the value objects for you and use it to initialize the ComplexEntity?
  2. Have essentially CLR basic types being passed to the factory and you construct every ValueObject that makes up the Entity?

I am leaning towards option 2 but I can't seem to find supporting literature for it.

Edit 1

To be honest I am still no clearer. What about aggregate roots?

When my entity refers to other entities, e.g. below.

  1. Should I have an IComplexEntityFactory, ILessComplexEntityFactory? Or just an IComplexEntityAggregateFactory that creates the LessComplexEntity and instantiates ComplexEntity ?
  2. In the case of the AggregateFactory solution, what do I do if the LessComplexEntity attribtues that have been passed to the factory correspond to an existing LessComplexEntity? Do I retrieve and reuse it from a Repository? Or do I return an error to the caller?
  3. What would the method signature be for the AggregateFactory? Would it be (ValueObject a, ValueObject b), or (ValueObject value, LessCompelxEntity entity)

    public class ComplexEntity { private readonly int _id; public int Id { get { return _id;} }

    public ValueObject Value {get; set;}
    public LessComplexEntity Entity {get; set;}
    
    public ComplexEntity(int id, ValueObject value, LessComplexEntity entity)
    {
    }
    

    }

    public class LessComplexEntity { private readonly int _id; public int Id { get {return _id;} } public ValueObject Value {get; set;} public LessComplexEntity(int id, ValuObject value) { } }

like image 945
M Afifi Avatar asked Jul 09 '12 12:07

M Afifi


People also ask

What is the difference between Entity and value object in DDD?

The main difference between entities and value objects lies in the way we compare their instances to each other. The concept of identifier equality refers to entities, whereas the concept of structural equality - to value objects. In other words, entities possess inherent identity while value objects don't.

What is a DDD value object?

Value Object is an object that represents a concept from your problem Domain. It is important in DDD that Value Objects support and enrich Ubiquitous Language of your Domain. They are not just primitives that represent some values - they are domain citizens that model behaviour of your application.

Can a value object contain an Entity?

Yes it can. This would be a relatively obscure case but DDD allows for it and it can be useful. From the DDD book by Eric Evans: VALUE OBJECTS can even reference ENTITIES.

What are DDD factories?

A Factory is an object that has the sole responsibility to create other objects. Factories are definitely not unique to Domain Driven Design, but they do hold an important role within a Domain Driven Design project.

What are entities and value objects in DDD?

Entities and Value Objects in C# for DDD 1 Domain Driven Design. The term was coined by Eric Evans. ... 2 Entities. An object fundamentally defined not by its attributes, but by a thread of continuity and identity. ... 3 Value Objects. An object that describes some characteristic or attribute but carries no concept of identity. ... 4 Json.NET. ...

What is the factory pattern in DDD?

The factory pattern in DDD can be seen as a super pattern for the Gang of Four (GoF) creational patterns. Factories are concerned with creating new entities and value objects. They also validate the invariants for the newly created objects. We can place a factory on the entity or value object itself or an independent object.

What is DDD and how does it work?

With DDD we focus on the core domain and domain logic and value the collaboration between technical and domain experts Two important building blocks when we talk about code are entitiesand value objects. Entities An object fundamentally defined not by its attributes, but by a thread of continuity and identity. An entity: has an identity

What are entities and Vos in DDD?

Entities and VOs are two of the building blocks in DDD expressing the model. They are the starting points for Domain-Driven Design (besides Services and Domain Events). Besides just looking at the definitions of Entity and VO, I will also provide you with some guidance on how to distinguish them.


1 Answers

I'd choose option 1.

  • Makes explicit to everyone that you need a ValueObjectA to build a ComplexEntity. More readable, less head scratching when you see the method used somewhere.

  • If ValueObjectA changes, you'll have to modify the code in only one place (the factory's caller) as opposed to changing the signature of Create() + adjusting the value object creation inside the factory.

  • Less parameters to the factory's Create() method is less verbose and more readable.

  • In unit tests, it gives you a lot more options to be able to inject the ValueObjectA you want. There's not a lot you can do in terms of testing if you keep ValueObjectA's creation hidden inside the factory entirely.

[Edit]

It's not clear what your real problem is with Aggregate Roots and Factories, but you shouldn't mix up the responsibility to retrieve/rehydrate an existing object with the responsibility to create an object.

I'd take as a general rule that a Factory's job is to assemble a new object from smaller parts (whether they be primitive types, value objects, entities...)

The Factory should be provided with all these parts, it is not its duty to retrieve or rehydrate them from somewhere. You can leave that to the Factory's caller. It will make the Factory more cohesive and coupled to less classes (Repositories, etc.)

like image 132
guillaume31 Avatar answered Sep 19 '22 16:09

guillaume31