I really want to give some thought to this situation, I want to map addresses and properties. The address table is filled based on the information retrieved from google maps and inserted on the table. Repetition is present on the table, if a two different people register two properties on the same address (neighbors) (no property number is inserted) the address table will have two identical address with two different ids. I have two design ideas and both will work fine, no doubt about it but both seem weird somehow.
My first design, I will have each property table have and address_id.
Why it is weird for me, "it seems that the address table owns a property (the foreign key in the "main entity") when it is the opposite the property owns an address.
My second design, the address table will have two column to find the correct "property".
The property type and property id.
which design should I use. There's some other better option?
I simplified things a little, but the idea is 100% here.
The first design is, for most generic requirements, the standard implementation. A property has an attribute of an address
Related
I have a position, and some entities that use position as it's identifier (geography, biome, and so on). If I want to get acess to them, I would need to retrieve each one by it's position, which would cause repeated code. On the other hand, I could create a class that is a container, like a "location". But, in this case, to retrieve geography (for example), I would need to break demeter's law.
Repository.getLocation().getGeography().getHighestPeak();
Is there any other approach to this, or a common pattern that I'm missing? Keep in mind that this type of objects (that relate to position in the way I described) are very likely to grow large in number after a few months.
I'm not sure it's a good idea to have a Position as an ID
The Position of an entity is likely to change, which leads to an unstable identifier.
You won't be able to have multiple instances of a given entity with the same position.
On the other hand, I could create a class that is a container, like a
"location". But, in this case, to retrieve geography (for example), I
would need to break demeter's law.
Repository.getLocation().getGeography().getHighestPeak();
You're basically saying that a Location has an entity, which is a bit awkward. It seems much more natural to say that an entity has a position. How about
GeographyRepository.getGeographyByPosition(new Position(...)).getHighestPeak();
?
I’m struggling designing this system where an address is the most central piece of information. Now in this case, an address is not just a few lines of strings. We’re storing municipalities (code, name), district (post code, name), streets (code, name), house number on a street in a specific district belonging to a municipal. It's a very normalized scheme.
So we have the entities Municipal, District, Street and HouseNumber each with relations to each other, defining a complete address for a person (or something else).
Now I have been trying to figure out if it would make any sense having an aggregate root named Address? An Address entity (aggregate root) would then have references to HouseNumber, Street, District and Municipal. Then a person would be associated to an Address.
Strictly speaking this aggregate root is not necessary, but if I don’t have it, I would have to traverse many objects to obtain the full address. Does it make any sense to create an aggregate root based on that argument?
A person will never reference anything but the aggregate root in this case, however the UI might display only Municipalities (when browsing addresses, etc.). Is this a violation of the aggregate root idea?
I would really like your advice and take on this problem. Any help will be much appreciated!
A little update from another discussion about my problem:
There is some invariants needed to be managed in the aggregate. For example; I
can't have a house number on a street thats in one district/municipality, where
the postal box is in another different district/municipality. So when assigning
a post box to an address/person, I need to make sure that they are in the same
district.
Also there are some consistency boundaries (if I understood this concept the
right way). If I have an address, this must have a house number in a district on
a street (in that district). A street can span multiple districts so it's
important to ensure that the house number on that street is in the correct
district.
Update about designing the aggregate:
A house number is actually the entry point for an address. A house number is associated with a street and a district. So a person is associated to a house number. What I also want to define is if a person has "postal responsibility" for that house number. Introducing the aggregate root Address, makes the person associate with that instead of the house number. In the database, the aggregate Address will contain a 1-1 association to a house number, and the Address has a 1-* to a Person. Where should I store the value indicating that the person has postal responsibility or not? Should I do this in the Address aggregate? Or where would
you put it? And the same goes for my entities - where should I indicate if the person has a postal responsibility?
To distinguish if address is value object or entity, ask Yourself a question - if person address changes and 2nd person had same address - will both change? If they both changes - address gets promoted to entity (cause address identity is important and not value).
To distinguish if address is entity or an aggregate root, ask Yourself a question - does address make any sense on it's own or it's always tied to person, is modified through it, deleted together with it? If it's not tied with person but exists on it's own (in model You are modeling and not reality), then address is an aggregate root.
Strictly speaking this aggregate root is not necessary, but if I don’t have it, I would have to traverse many objects to obtain the full address. Does it make any sense to create an aggregate root based on that argument?
No it does not. Technical issues shouldn't mess with Your domain. Entity can work as a 'sub-aggregate', address can hold together municipality, city, etc. and still be just an entity (cause it makes no sense w/o person).
A person will never reference anything but the aggregate root in this case, however the UI might display only Municipalities (when browsing addresses, etc.). Is this a violation of the aggregate root idea?
Presentation shouldn't mess with Your domain too. As far as i see - it's perfectly fine if You are showing only list of entities and hiding aggregates they belong to.
Two persons can be associated to the same address, and if one of them move the other doesn't move automatically.
Question is - how You want to model that moving process?
I see 2 ways:
When person #1 moves, address is modified but address of person #2 is not the same address and hence - is not affected. In this case - address is just an entity.
When person #1 moves, moving process switches address to another one. In this case - address is an aggregate root.
Addresses exists on their own and if a person move to an address, he gets associated with it.
This one means that You want to stick with 2nd way (when address is an aggregate root). It's fine and there is nothing wrong, but You should re-check if address can be demoted to entity cause that would make Your domain model less complex.
And keep in mind - there isn't "The model", there are only "A model"s. You can't model reality to mimic it perfectly, You can only model some part of it to solve specific problems.
This is why it's so hard to answer ddd related questions.
No one knows Your problems You are trying to solve.
If I understand it correctly (http://msdn.microsoft.com/en-us/magazine/dd419654.aspx - the part about aggregates), then whether an address can exist without a person (or other addressee) is irrelevant; the question is whether the address-constituents can exist or be accessed without the address. If they can, Address shouldn't be an aggregate root.
It is relevant. If address can't exist without a person (which is not a case here) - it's inevitably demoted as an entity (cause it makes no sense without person) or value object (if address itself has no identity). Otherwise - You are just introducing unnecessary aggregate root.
It's fine if aggregate root contains references to other aggregate roots (but not entities of other aggregate roots). Therefore - address constituents can be aggregate roots too (Municipality that is referenced in PostOffice) and that wouldn't change if address itself is entity or an aggregate root.
Aggregate, in my opinion, should be created if
there is a containment
relationship with its associated
objects
the objects of an
Aggregate are stored in a database,
and only the root should be
obtainable through queries. The
other objects should be obtained
through traversal associations.
and you have invariant rules that u need to enforce uniformly across the contained objects
your scenario doesn't seem to satisfy either of those 2. so my opinion is no
Also read this post and provided answers: DDD: Aggregate Roots
Whether Address should be a separate entity should not be driven by technical concerns.
The way you talk about an address tells me it is a separate entity made up of the constituent parts you mentioned.
The fact that the Address persists even when it isn't tied to a Person or another class, also is a clue that it should be its own entity.
Furthermore: Address can be used not just be a Person, but by other things (classes) as well. Do you really want to burden each class that can have an address to have to deal with how to form it from its consituent parts?
The fact alone that you are talking about an Address as a specific concept is enough to make it a separate class. Even in the case where an address would only exist as long as it is tied to another class, it would make sense to create a separate class, possibly a nested class in that case, just to separate the logic dealing with the address from the logic dealing with the rest of the person's attributes.
Update
If I understand it correctly (http://msdn.microsoft.com/en-us/magazine/dd419654.aspx - the part about aggregates), then whether an address can exist without a person (or other addressee) is irrelevant; the question is whether the address-constituents can exist or be accessed without the address. If they can, Address shouldn't be an aggregate root.
On the one hand an Address should be an aggregate of its constituent parts. But, the constituent parts of an address seem to be independent of address and can exist without it. After all, a municipality or street can exist without a "door" being present in either. So, I would say that this disqualifies Address as an aggregate root in DDD terms.
Update
As Tommy mentioned (see comments): A better question would be "Will the system ever manipulate a street/municipality directly, or will it always be the whole address?"
I would consider that selecting a municipality from a list in order to construct an address isn't "direct manipulation" when it is always done in the context of constructing an address. Similarly, I would not consider maintaining that list of municipalities "direct manipulation" if it is only maintained for use by an address.
Update
As Arnis points out, whether Address can exist independently of Person (or another entity) is relevant in as much as that dictates whether Address is an entity in its own right. As I understand it now, only entities can be aggregate roots.
There are some simple entities in an application (e.g containing only id and title) which rarely change and are being referenced by the more complex entities of the application. These are usually entities such as Country, City, Language etc.
How are these called? I've used the following names for those in the past but I'm not sure which is the best way to call them:
reference data
lookup values
dictionaries
thanks
You tagged with "ddd", so assuming that you are looking for a more Domain-Driven Design approach, drop the identifier on these objects and treat them like Value Objects.
The reason you might consider dropping the identifier is that it adds unneeded complexity to the problem domain. For example, you have a "Country" table in your implementation, I am assuming? You would still have it, but it wouldn't be a referential lookup. You would use it purely as "reference data". Load it upfront for scenarios where it needs to be referenced - maybe your UI is binding it to a dropdown list, for example...
When the entity is saved or updated, you store the value of the object, hence the "value" "object". If the user changes the entity for another value, no problem, just update the value. It is one less associative lookup that has to be made when doing CRUD operations, which makes the overall model less complex.
I would say Reference Data
See link text
I have a situation in which the ideal relationship, I believe, would involve Value Object Inheritance. This is unfortunately not supported in NHibernate so any solution I come up with will be less than perfect.
Let’s say that:
“Item” entities have a “Location” that can be in one of multiple different formats.
These formats are completely different with no overlapping fields.
We will deal with each Location in the format that is provided in the data with no attempt to convert from one format to another.
Each Item has exactly one Location.
“SpecialItem” is a subtype of Item, however, that is unique in that it has exactly two Locations.
“Group” entities aggregate Items.
“LocationGroup” is as subtype of Group.
LocationGroup also has a single Location that can be in any of the formats as described above.
Although I’m interested in Items by Group, I’m also interested in being able to find all items with the same Location, regardless of which group they are in.
I apologize for the number of stipulations listed above, but I’m afraid that simplifying it any further wouldn’t really reflect the difficulties of the situation. Here is how the above could be diagrammed:
Mapping Dilemma Diagram http://www.freeimagehosting.net/uploads/592ad48b1a.jpg
Analyzing the above, I make the following observations:
I treat Locations polymorphically, referring to the supertype rather than the subtype.
Logically, Locations should be “Value Objects” rather than entities since it is meaningless to differentiate between two Location objects that have all the same values. Thus equality between Locations should be based on field comparisons, not identifiers. Also, value objects should be immutable and shared references should not be allowed.
Using NHibernate (or Hibernate) one would typically map value objects using the “component” keyword which would cause the fields of the class to be mapped directly into the database table that represents the containing class. Put another way, there would not be a separate “Locations” table in the database (and Locations would therefore have no identifiers).
NHibernate (or Hibernate) do not currently support inheritance for value objects.
My choices as I see them are:
Ignore the fact that Locations should be value objects and map them as entities. This would take care of the inheritance mapping issues since NHibernate supports entity inheritance. The downside is that I then have to deal with aliasing issues. (Meaning that if multiple objects share a reference to the same Location, then changing values for one object’s Location would cause the location to change for other objects that share the reference to the same Location record.) I want to avoid this if possible. Another downside is that entities are typically compared by their IDs. This would mean that two Location objects would be considered not equal even if the values of all their fields are the same. This would be invalid and unacceptable from the business perspective.
Flatten Locations into a single class so that there are no longer inheritance relationships for Locations. This would allow Locations to be treated as value objects which could easily be handled by using “component” mapping in NHibernate. The downside in this case would be that the domain model becomes weaker, more fragile and less maintainable.
Do some “creative” mapping in the hbm files in order to force Location fields to be mapped into the containing entities’ tables without using the “component” keyword. This approach is described by Colin Jack here. My situation is more complicated than the one he describes due to the fact that SpecialItem has a second Location and the fact that a different entity, LocatedGroup, also has Locations. I could probably get it to work, but the mappings would be non-intuitive and therefore hard to understand and maintain by other developers in the future. Also, I suspect that these tricky mappings would likely not be possible using Fluent NHibernate so I would use the advantages of using that tool, at least in that situation.
Surely others out there have run into similar situations. I’m hoping someone who has “been there, done that” can share some wisdom. :-)
So here’s the question… Which approach should be preferred in this situation? Why? Is there a better option that I haven't considered?
Just a few observations / questions...
if the different location formats have no overlapping fields, what is the commonality in them which would make them candidates for a subclass hierarchy? Can you actually define a common interface for the base class Location?
is a TypeALocation comparable with a TypeBLocation?
are the two locations in SpecialItem of the same type, or can they be mixed?
can an item change its location to a different type runtime?
As you state above, value objects can't be polymorphic. Based on what you describe, I don't see how can you treat locations polymorphically.
Update If you can't define a common base interface for your location types, it is very awkward to try and treat them polymorphically, regardless of whether there is ORM or not. Taking your example below, even for accessing any information about the actual location I live, you needed to downcast it to either a street address or a lat/long coordinate. Polimorphism is meant exactly to avoid the need for such downcasts (and switches on type fields, etc.)!
Looking at the options you describe above, with all this taken into account:
Just as you, I don't like it either (hardly suprising).
Can be a viable option if there aren't many location types and you can be reasonably sure that you have implemented all the types ever needed. In this case the domain class would practically be the analog of a C union, with a type field. It is a bit awkward to use, but the polymorphic attempt would be even more awkward IMHO.
It is definitely an interesting idea which I will probably experiment with in a pet project sometime, but I am not quite sure I would like such tricks in my production code. I guess it could also be done with a custom mapping type which would map your component to a specific subclass. But then again, we're back trying to fit these incompatible types into a type hierarchy... the only good reason to try this path is if there are many location types and/or new types may appear in the future.
context:
I have an entity Book. A book can have one or more Descriptions. Descriptions are value objects.
problem:
A description can be more specific than another description. Eg if a description contains the content of the book and how the cover looks it is more specific than a description that only discusses how the cover looks. I don't know how to model this and how to have the repository save it. It is not the responsibility of the book nor of the book description to know these relationships. Some other object can handle this and then ask the repository to save the relationships. But BookRepository.addMoreSpecificDescription(Description, MoreSpecificDescription) seems difficult for the repository to save.
How is such a thing handled in DDD?
The other two answers are one direction (+1 btw). I am coming in after your edit to the original question, so here are my two cents...
I define a Value Object as an object with two or more properties that can (and is) shared amongst other entities. They can be shared only within a single Aggregate Root, that's fine too. Just the fact that they can (and are) shared.
To use your example, you define a "Description" as a Value Object. That tells me that "Description" with multiple properties can be shared amongst several Books. In the real-world, that does not make sense as we all know each book has unique descriptions written by the master of who authored or published the book. Hehe. So, I would argue that Descriptions aren't really Value Objects, but themselves are additional Entity objects within your Book Aggregate Root Entity boundery (you can have multiple entities within a single aggregate root's entity). Even books that are re-released, a newer revision, etc have slightly different descriptions describing that slight change.
I believe that answers your question - make the descriptions entity objects and protect them behind your main Book Entity Aggregate Root (e.g. Book.GetDescriptions()...). The rest of this answer addresses how I handle Value Objects in Repositories, for others reading this post...
For storing Value Objects in a repository, and retrieving them, we start to encroach onto the same territory I wrestled with myself when I went switched from a "Database-first" modeling approach to a DDD approach. I myself wreslted with this one, on how to store a Value Object in the DB, and retrieve it without an Identity. Until I stepped back and realized what i was doing...
In Domain Driven Design, you are modeling the Value Objects in your domain - not your data store. That is the key phrase. It means you are not designing the Value Objects to be stored as independant objects in the data store, you can store them however you like!
Let's take the common DDD example of Value Objects, that being an Address(). DDD presents that an Mailing Address is the perfect Value Object example, as the definition of a Value Object is an object of who's properties sum up to create the uniqueness of the object. If a property changes, it will be a different Value Object. And the same Value Object 9teh sum of its properties) can be shared amongst other Entities.
A Mailing Address is a location, a long/lat of a specific location on the planet. Multiple people can live at the address, and when someone moves, the new people to occupy the same Mailing Address now use the same Value Object.
So, I have a Person() object with a MailingAddress() object that has the address information in it. It is protected behind my Person() aggregate root with get/update/create methods/services.
Now, how do we store that and share it amongst the people in the same household? Ah, there lies DDD - you aren't modeling your data store straight from your DDD (even though, that would be nice). With that said, you simple create a single Table that presents your Person object, and it has the columns for your mailing address within it. It is the job of your Repository to re-hydrate that information back into your Person() and MailingAddress() object from the data store, and to split it up during the Create/Update operations.
Yep, you'd have duplicate data now in your data store. Three Person() entities with the same mailing address all now have three seperate copies of that Value Object data - and that is ok! Value Objects are meant to be copied and destoyed quite easily. "Copy" is the optimum word there in the DDD playbook.
So to sum up, Domain Drive Design is about modeling your Domain to represent your actual business use of the objects. You model a Person() entity and a MailingAddress Value Object seperately, as they are represented differently in your application. You persist them a copied-data, that being additional columns in the same table as your Person table.
All of the above is strict-DDD. But, DDD is meant to be just "suggestions", not rules to live by. That's why you are free to do what myself and many others have done, kind of a loose-DDD style. If you don't like the copied data, your only option is that being you can create a seperate table for MailingAddress() and stick an Identity column on it, and update your MailingAddress() object to have now have that identity on it - knowing you only use that identity to link it to other Person() objects that share it (I personally like a 3rd many-to-many relationship table, to keep the speed of the queries up). You would mask that Idenity (i.e. internal modifier) from being exposed outside of your Aggregate Root/Domain, so other layers (such as the Application or UI) do not know of the Identity column of the MailingAddress, if possible. Also, I would create a dedicated Repository just for MailingAddress, and use your PersonService layer to combine them into the correct object, Person.MailingAddress().
Sorry for the rant... :)
First, I think that reviews should be entities.
Second, why are you trying to model relationships between reviews? I don't see a natural relationship between them. "More specific than" is too vague to be useful as a relationship.
If you're having difficulty modeling the situation, that suggests that maybe there is no relationship.
I agree with Jason. I don't know what your rationale is for making reviews value objects.
I would expect a BookReview to have BookReviewContentItems so that you could have a method on the BookReview to call to decide if it is specific enough, where the method decides based on querying its collection of content items.