2

I have an address as part of my domain. The address keeps information about country, city, zipcode, street and housenumber. It is used in multiple places - a company can have an office address, invoicing address and/or correspondence address; transports have addresses at start, middle and end points; couple of other places, too.

I'm wondering how to correctly handle this DDD-way. Should address be a value object, an entity or an aggregate root? I've seen similar questions but not surprisingly none of those corresponded well with my domain.

An address doesn't know how to validate itself - company's addresses can be initially almost empty and filled later, but transport's addresses should be always complete. So generally it depends on the object containing an address, not on the address itself.

Next thing is that address of one company is completely independent from addresses in other companies - event if they are the same in terms of location. Also, changing company's address doesn't mean replacing it with another - it is just an update done to the current object. It also doesn't affect other any other address. Does that alone qualify address as an entity?

As address can't function on it's own, it shouldn't be AG, right?

Maybe address should be just an interface with CompanyAddress, TransportAddress etc. implementing it? They are following different rules after all...

I'd really appreciate your opinion about this. I feel like I'm missing something here, but can't quite figure out what exactly.

3 Answers 3

3

It sounds to me like you actually have two distinct objects here, Address and Location. A Location could be used to represent a corporate office or some other conceptual place, but an Address would be a value object that represents a physical location. An Address never changes, but the Address property of a Location can be changed from one Address value object to another with an appropriate event.

1

I feel like I'm missing something here but can't quite figure out what exactly.

One thing that is easy to loose track of is that entities enclose values. Which is to say, entities "have" current state, and state is a value.

See Stuart Halloway's talk, Perception and Action.

What an entity is is a mutable reference to immutable state.

State before = mutableRef.get()
State after = computeNextState(before)
mutableRef.swap(before, after)

Put another way, an entity is a temporally varying mapping to state.

We need to be careful in our modeling in terms of understanding when we want to be referring to a reference (which gives us access to different state, depending on when we dereference it), and when we want state.

Consider a shipping example; you may have a current default shipping address; when you place an order, your order also needs a shipping address. Riddle: if you change your default shipping address after placing an order, should the destination of your shipment change? Does it matter if we ask that question before the package has left the fulfillment center?

Another is that semantically different values may have a common representation, and it's important not to confuse the two. For example, UnvalidatedEmailAddress and ValidatedEmailAddress are semantically different, but the representations in bytes probably still look like [email protected].

Scott Wlaschin has some accessible materials that detail this, and his new book, Domain Modeling Made Functional, is quite good.

Part of the point is to take implicit semantic distinctions, like the different between Company.Address and Transport.Address, and make them explicit.

1
  • Actually, something like your shipping example happens in my domain a lot, but every shipment gets its own delivery address based on client's default shipping address the moment it is created in system. Both addresses can reference same country, city, etc, but those are immutable, so changing e.g. city in one address is actually switching references - one does not affect the other. This may however produce some orphan cities but that's acceptable. That being said, I see now that company address is something different than transport address. Stuart's talk was very interesting too, thanks a lot!
    – webfreak
    Commented Feb 8, 2018 at 16:32
0

Address in Company and Transport , sounds like a good example of similar entity (Address) used in multiple bounded context with diff. business rules.

So if your Company Address has diff. business rule and Transport Address has diff. business rule for sure you need diff. Object type like CompanyAddress and TransportAddress

Now the question comes in should they be AggregateRoot, ValueObject or Entity,i think they can be anything based on how your business models them , i would prefer them as Aggregate Root in case of Company and and as ValueObject in case of Transport

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.