Why should I avoid creating public setters for domain entity properties

I am trying to apply DDD in one of the applications that I am currently working on, and I cannot say that I understood this 100%.

In most of the examples that I look at, it seems that we are trying to avoid public settings on the properties of the essence of the domain. For example, I see domain objects implemented as shown below:

public class Product
{
    public Product(string name)
    {
        if (name == null)
        {
            throw new ArgumentNullException("name");
        }

        Name = name;
    }

    public string Name { get; private set; }

    public void UpdateName(string newName)
    {
        if (newName == null)
        {
            throw new ArgumentNullException("newName");
        }

        Name = newName;
        DomainEvents.Raise(new ProductNameUpdatedEvent(this));
    }
}

Usage will look something like this:

// have a Product object instance here somehow
product.UpdateName("foobar");

However, I can achieve the same behavior by embedding update logic in the Namesetter property, as shown below:

public class Product
{
    private string _name;

    public Product(string name)
    {
        if (name == null)
        {
            throw new ArgumentNullException("name");
        }

        _name = name;
    }

    public string Name
    {
        get
        {
            return _name;
        }

        set
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            _name = value;
            DomainEvents.Raise(new ProductNameUpdatedEvent(this));
        }
    }
}

In this case, the usage will look something like this:

// have a Product object instance here somehow
product.Name = "foobar";

, , . , , ? DDD, -, ?

+4
2

DDD - . CRUD (Create/Read/Update/Delete) . , ?

, , , , .

, , product.name = 'some name', ? , Product , , . , , .

product.rename(...) , . , .

, , , ? , ? ? ?

#, , , -, :

public class Product {

    //Note: Using ProductName rather than string would be helpful
    //to protect further invariants (e.g. name cannot be empty string)
    private string _name;

    public Product(string name) {
        Name = name;
    }

    public string Name {
        get {
            return _name;
        }

        private set {
            if (value == null) {
                throw new ArgumentNullException("A product must be named");
            }

            _name = value;
        }
    }

    public void rename(string newName) {
        string oldName = Name;

        Name = newName;

        //Assume the entity has the supporting code for a  unique identifier
        //productId
        DomainEvents.Raise(new ProductRenamed(productId, oldName, newName));
    }
}

, . - , , - , . . , .

+5

, .

- : http://www.jayway.com/2013/06/20/dont-publish-domain-events-return-them/

, , , - , .

:

  • DomainEvents, .
  • , singleton DomainEvents.

, , , , . , :)

0

All Articles