22

Consider a system that uses DDD (as well: any system that uses an ORM). The point of any system realistically, in nearly every use case, will be to manipulate those domain objects. Otherwise there's no real effect or purpose.

Modifying an immutable object will cause it to generate a new record after the object is persisted which creates massive bloat in the datasource (unless you delete previous records after modifications).

I can see the benefit of using immutable objects, but in this sense, I can't ever see a useful case for using immutable objects. Is this wrong?

1

8 Answers 8

18

Computation using immutable objects (as in functional programming) does not necessarily imply persisting every object that is generated!

2
  • I'm not seeing an instance where that scenario makes use of immutable objects anyway though - so they'd be there for no particular purpose. Am I wrong? Commented Nov 29, 2010 at 21:56
  • 1
    i was thinking that the immutable objects would be useful for intermediate calculations (in parallel threads) Commented Nov 29, 2010 at 22:01
11

Does immutable in the domain mean it has to be immutable in the database? For example consider the following assuming customer always has one address:

customer.address = new Address('My Castle', 'Kings street');
customer_repo.save(customer);

now the following sql is run considering the customer id is 1:

INSERT INTO addresses (customer_id, name, street)
VALUES (1, 'My Castle', 'Kings street');

now the following change is made to the address:

customer.address = new Address('Pauper palace', 'Outlands');
customer_repo.save(customer);

and the persistence layer, being very clever runs the following sql:

UPDATE addresses SET name='Pauper palance', street='Outlands'
WHERE customer_id = 1;

This way you avoid the overhead of a separate DELETE AND INSERT statement. Also I think some RDBMSs have INSERT REPLACE or something. MySql has REPLACE.

11
  • +1 I agree with you on the general principle: I don't see why immutable domain objects must necessarily mean immutable DB rows.
    – Andres F.
    Commented Jun 6, 2012 at 13:58
  • In the above case if we ever needed to change the city attribute of the address class for a given customer how would we handle it ?, Further assume customer could have multiple addresses so it a a one to many relation ship between customer and addresses
    – Sudarshan
    Commented Oct 17, 2012 at 16:50
  • 1
    @Sudarshan this is just a way to make an 'immutable value object', not really immutable in the database. For performance reasons. Each situation needs to be handled specifically ofcourse. I prefer Event Sourcing for my Domain now, but I am kind of addicted to it.
    – andho
    Commented Oct 25, 2012 at 10:12
  • @Sudarshan to answer your question specifically, You just run an update query which updates the row to the new value. If it is one-to-many, then the addresses will have some kind of identifier within the Customer Aggregate Root which will be used to uniquely identify it in the DB. Then this identifier and customer_id will be used to update that row in the 'address' table.
    – andho
    Commented Oct 25, 2012 at 10:15
  • @andho " this is just a way to make an 'immutable value object', not really immutable in the database." this really made my day thanks
    – Sudarshan
    Commented Oct 25, 2012 at 13:23
6

In DDD, immutable objects pretty much equate with value objects. These objects aren't entities, they don't have an identity. Therefore I always persist value objects as colums of the entity they are contained in (with N/Hibernate you can use Components for that). They don't have a table of their own.

4

It depends on how the immutable object is mapped in the database. If it's just a component like a DateTime (from the Joda Time library) then changing the value will result in an update rather than an insert. However, if the immutable is more complex requiring a row in a table then you've got the bloat problem.

I suppose, although it is a weak argument, you could implement an audit trail this way. Every change to the immmutable can be tracked through the inserts. There are many better ways to do this though.

All in all having immutable domain objects (instead of merely their components) seems a bit of a mismatch with persistence.

3
  • Not at all. Components are very useful since they allow domain objects to be composed differently from the same underlying data. The problems come with enforcing immutability. Personally, I would treat domain objects as mutable (with the exception of the primary key fields) and keep it simple.
    – Gary
    Commented Feb 20, 2013 at 11:22
  • "All in all having immutable domain objects (instead of merely their components) seems a bit of a mismatch with persistence." In you're opinion where would we need to have value objects which should not be modeled as components (Hibernate terminology) ? --- Sorry I had mistyped my last comment and hence deleted it.
    – Sudarshan
    Commented Feb 21, 2013 at 8:24
  • Avoid components when a single entity is fully represented by a row and none of the data is shared by another domain object.
    – Gary
    Commented Feb 21, 2013 at 11:09
4

That depends on the domain. DDD doesn't specify that the programming paradigm is object oriented. The object oriented paradigm is however one well suited for the typical application that must be persisted in a database.

DDD simply states that you should build your software around a domain model that represents the actual problem that the software is trying to solve. If that problem was for example mathematical by nature, then implementing the domain layer using functional programming and immutable data structures would make a lot of sense.

If on the other hand, the problem is more of a typical enterprise application, and you are using immutable object structures for all your domain objects, then I would argue that you are not following DDD. I can come up with at least two arguments:

  • Your implementation does not represent a domain model of your problem domain. Your problem domain in this case consists of entities having state to modify. And that is not how you have implemented it.

  • You do not have an ubiquitous language. The language and the concepts in the domain model do not follow what the domain experts are using.

Note: DDD does use immutable objects where appropriate, they are just called value objects.

So I'm not saying that you cannot create a database application using purely functional data structures, and I'm not saying that you shouldn't. I just don't think you can call it DDD, depending on the type of application

1
  • Peter, great answer. Could you take a look at my question here stackoverflow.com/questions/13783666/… and help me figure out my problem. I think immutable value objects are great for softwares that are not enterprise related. Most enterprise applications's objects are mutable in my opinion. Imagine having a immutable deep-nested value object... ContactInfo->PhysicalLocation->Address and you want to update the zipcode... creating the whole object graph seems to me antichrist, not just an antipattern. what do you think? Commented Dec 12, 2012 at 4:35
3

If you are using an ORM such as Hibernate / NHibernate you can set your cascade option to automatically delete orphaned objects. If a person has a value object Address, when you change the address, the new one will be saved and the old one deleted because it is now orphaned.

0

Value objects are almost always immutable in DDD and the flyweight pattern can be used to keep duplication of that value object down in memory just like .NET does with strings. The main tradeoff is memory one one side and the other side is creational efficiency. With the flyweight pattern, a value based comparison must be done to determine whether any new or reconstituted value object is already within the flyweight cache but any other comparison after that point can be generally safely done by reference since a single instance is enforced. Either way whether flyweight is used or not, value objects are still made immutable because they have only intrinsic identity and thus changing their value would change their identity.

-1

There is another way to use immutable objects...

Instead of storing a values 5.0, 6.0, 7.0, 8.0 and copying the whole record every time, you can instead store something like this: 5.0, +1.0, +1.0, +1.0, and then build a dependencies correctly to reconstruct the sequence 5.0, 6.0, 7.0, 8.0. This way small modifications only take small amount of memory...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.