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
Related
I'm in doubt of how to get the best of ABAP structures and class attributes.
Let's say that I have the object Operation with 4 fields: operation id, type, description and date.
Now I can create a class with this 4 attributes, but then if I want to have a constructor, I need either 4 individual parameters or a structure than needs to be mapped to each attribute. The same happens if I want to get all this object data in one structure, for instance to return via RFC. Then a method get_operation_details( ) will need to map all of them one by one.
If I use a structure type ty_operation_details as a single class attribute, then when I add a field to the structure would also keep the constructor valid and the get_operation_details( ) method would also be always OK. However it seems wrong to have something like Operation->get_details( )-operationID, instead of operation->operation_ID if I had the attribute directly in the public section with READ-ONLY. I guess the first approach is more correct in the OO world, but we lose some of the ABAP benefits.
What do you recommend to use? Maybe one thing it could allow the first option and use structures at the same time would be a CORRESPONDING statement able to map class attributes to a flat structure, but I don't think this is possible.
Like most things, your design should follow your usage. If you primarily use a set of attributes together, consider grouping them in a structure. If you primarily use them individually, or in varying recombinations, keep them separate.
Some considerations:
Grouping makes calls shorter if you always create/update/delete a set of attributes together. You already identified this advantage.
Grouping reveals logical relations between fields, that are not clear when keeping the fields separate. For example, this could reveal that one part of your parameters is mandatory, while the rest forms several optional sets.
Grouping simplifies features that operate on state, such as the Memento or the Flyweight pattern, in that it allows to extract, store, and restore the object's state as a single structure.
Also, like many other things, there may be benefit in turning this either-or question into a I'll simply use both. For example, if your class has four individual properties, why not still offer a method that sets or gets them as a structure; of course, this will add some mapping, but the mapping would remain encapsulated within your own class, while consumer get an easy-to-consume interface.
There is one question that I often ask myself while designing a program, and I am never quite sure how to answer it.
Let's say I have an object with multiple fields, amongst which there is one serving as the identifier to that specific object. Let's also say that I need to keep track of a List of such objects somewhere else.
I now have three, and probably even more, options on how to go about it:
Have my object contain its own identifier, and all its other fields. I now use a simple array (or whatever simple list collection) of my objects where I need it. When I am looking for one specific object, I loop through my list and check for identifier equality.
Pros: 1. "Clarity" for each object instance. 2.?
Cons: Manipulating a collection of these objects gets annoying
Have my object contain all fields beside its identifier. I now use a Map with identifier as key, and object as value. When looking for one specific object, I just lookup the identifier in the map.
Pros: easy lookups and insertions,?
Cons: object instance itself doesnt know what it is,?
Combination of both: use a map with identifier as key and object having its own identifier as a field as value.
Pros: mentioned above.
Cons: looks redundant to me.
What situations would call for what? Let's use the standard hello-world example of networking for example, a chat server: how would I handle multiple "groups/channels" people are in?
What about other applications?
Your question is very wide and, actually, contains two questions.
First is “Which data structure is better — dictionary or list?”. The answer is: it depends on performance you want to achieve on insertion and search operations. Basically if you need to look through the collection, then list is ok, and if you need to have fast look-up, then dictionary is better. Dictionary has more memory overhead than list.
The second is “Do I need to have an Id field inside an entity or can I use built in hash code?”. The answer is: it depends on how you will use your object. If you want Id just to store it in a dictionary, then, most likely, you can go with hash code. There is nothing wrong with storing Id of an entity inside that entity. Either you use Id or hash code, you need to be sure that this entity will be uniquely identified by id or hash. That's the main concern with it.
You can override GetHashCode method and make it return Id of your entity. Sometimes you can find such implementation when hash code is required for collection and Id is required for database.
So, it really doesn't matter what you will choose in the end if both approaches are working for you right now.
A map<Identifier, Object> will offer you O(1) performance when retrieving an object based on its identifier. There certainly are situations where you want to achieve that.
However, in other cases it might be redundant to use this approach. It all depends on the situation at hand.
Two guidelines may answer this question:
A use case that calls for a lookup where there is an expectation of a 1:1 relationship between the key and value implies a Map structure.
OOP implies that a key which is so closely related to an object as to preform a lookup should be encapsulated within that object.
Regarding the question of redundancy, consider the key in a map is nothing but an index. Indexes are as common in data as in books.
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.
I'm trying to follow DDD, or a least my limited understanding of it.
I'm having trouble fitting a few things into the DDD boxes though.
An example: I have a User Entity. This user Entity has a reference to a UserPreferencesInfo object - this is just a class which contains a bunch of properties regarding user preferences. These properties are fairly unrelated, other than the fact that they are all user preferences (unlike say an Address VO, where all the properties form a meaningful whole).
Question is - what is this UserPreferencesInfo object?
1) Obviously it's not an Entity (I'm just storing it as 'component' in fluent nhibernate speak (i.e. in the same DB table as the User entity).
2) VO? I understand that Value Object are supposed to be Immutable (so you cant cange them, just new them up). This makes complete sense when the object is an address for instance (the address properties form a meaningful 'whole'). But in the case of UserPreferencesInfo I don't think it makes sense. There could be 100 properties (Realistically) There could be maybe 20 properties on this object - why would I want to discard an recreate the object whenever I needed to change one property?
I feel like I need to break the rules here to get what I need, but I don't really like the idea of that (it's a slippery slope!). Am I missing something here?
Thanks
Answer 1 (the practical one)
I'm a huge proponent of DDD, but don't force it. You've already recognised that immutable VOs add more work than is required. DDD is designed to harness complexity, but in this case there is very little complexity to manage.
I would simply treat UserPreferencesInfo as an Entity, and reference it from the User aggregate. Whether you store it as a Component or in a separate table is your choice.
IMHO, the whole Entity vs VO debate can be rendered moot. It's highly unlikely that in 6 months time, another developer will look at your code and say "WTF! He's not using immutable VOs! What the heck was he thinking!!".
Answer 2 (the DDD purist)
Is UserPreferencesInfo actually part of the business domain? Others have mentioned disecting this object. But if you stick to pure DDD, you might need to determine which preferences belong to which Bounded Context.
This in turn could lead to adding Service Layers, and before you know it, you've over-engineered the solution for a very simple problem...
Here's my two cents. Short answer: UserPreferenceInfo is a value object because it describes the characteristics of an object. It's not an entity because there's no need to track an object instance over time.
Longer answer: an object with 100+ properties which are not related is not very DDD-ish. Try to group related properties together to form new VOs or you might discover new entities as well.
Another DDD smell is to have a lot of set properties in the first place. Try to find the essence of the action instead of only setting the value. Example:
// not ddd
employee.Salary = newSalary;
// more ddd
employee.GiveRaise(newSalary);
On the other hand you may very well have legitimate reasons to have a bunch of properties that are no more than getters and setters. But then there's probably simpler methods than DDD to solve the problem. There's nothing wrong with taking the best patterns and ideas from DDD but relax a little of all the "rules", especially for simpler domains.
I'd say a UserPreferenceInfo is actually a part of the User aggregate root. It should be the responsibility of the UserRepository to persist the User Aggregate Root.
Value objects only need to be newed up (in your object model) when their values are shared. A sample scenario for that would be if you check for a similar UserPreferenceInfo and associate the User with that instead of Inserting a new one everytime. Sharing Value Objects make sense if value object tables would get to large and raise speed/storage concerns. The price for sharing is paid on Insert.
It is reasonable to abstract this procedure in the DAL.
If you are not shraing value objects, there is nothing against updating.
As far as I understand, UserPreferenceInfo is a part of User entity. Ergo User entity is an Aggregate root which is retrieved or saved using UserRepository as a whole, along with UserPreferenceInfo and other objects.
Personally, I think that UserPreferenceInfo is entity type, since it has identity - it can be changed, saved and retrieved from repository and still be regarded as the same object (i.e. has identity). But it depends on your usage of it.
It doesn't matter IMHO how object is represented in the DAL - is it stored in a separate table or part of other table. One of the benefits of DDD is persistence ignorance and is ususally a good thing.
Of course, I may be wrong, I am new to DDD too.
Question is - what is this UserPreferencesInfo object?
I don't know how this case is supported by NHibernate, but some ORMs support special concepts for them. For example DataObjects.Net include Structures concept. It seems that you need something like this in NH.
First time ever posting on a blog. Hope I do it right.
Anyway, since you haven't showed us the UserPreferencesInfo object, I am not sure how it's constructed such that you can have a variable number of things in it.
If it were me, I'd make a single class called UserPreference, with id, userid, key, value, displaytype, and whatever other fields you may need in it. This is an entity. it has an id and is tied to a certain user.
Then in your user entity (the root I am assuming), have an ISet.
100 properties sounds like a lot.
Try breaking UserPreferenceInfo up into smaller (more cohesive) types, which likely/hopefully are manageable as VOs.