I am quite familiar with dealing with simple entity relationships, such as making a group that contains a collection of many items. However, I'm wondering how to achieve a particular relationship within my data structure.
Currently my data structure is made of entity Group and entity Item which has a one-to-many relationship from Group. The item exists only in a single group. However, it can also provide a link to another group as required.
So an analogy for the situation could be: Group = House, Item = Inhabitants. I live at a particular house, but I can also provide information about where to find other houses.
Another analogy could be: Group = Playlist, Item = Songs. I listen to the songs of the playlist, then when I get to a particular song I can (optionally) decide to switch to another playlist.
Now I am pretty sure this is not the way to achieve this behaviour. I had the notion that it should be an attribute rather than a relationship, but I don't know if there is a way to link attributes unrelated NSManagedObjects (that I know of).
I'm thinking that it's not impossible, just that it requires a little more understanding of databases to achieve. Any advice, tutorials would be greatly appreciated!
EDIT: This is my second attempt at the data structure. Instead of it being a relationship, I've made a integer identifier on the group, and particular items can store this identifier as necessary in the form of an attribute.
The otherGroupIdentifier would store a value equal to identifier on the Group entity. That way I can link through to it as explained previously. However, this certainly does not seem to be the cleanest way to implement Core Data. Maybe what I am looking for is not possible or too complex for a Core Data system?
Related
I'm new to DDD and I want to clearly understand each domain object structure and role:
Aggregate Root:
1.1. The only contact point the client can interact with the domain objects, the client should not be able to modify or create new Entities or value objects whiteout the aggregate root? (Yes/No)
1.2. Can an aggregate root contain only value objects ? for example User root, it contain only address, phone, things which are value objects as far as I understand. So is it a sign of bad design when your aggregate root contain only value objects? shall it contain only entities and via entities interact with value objects?
Entities: Shall the entities contain only value objects? or it can also contain other entities? can you give me a simple example please ?
Value Objects: shall I go ahead and encapsulate every primitive type in an value object? I can go deep and make every primitive type as an value object, for example: PhoneNumber can be a string or an value object which contains country code, number. the same thing can be applied to all other primitive type value such as name, email. So where to draw the line ? where to say "Ok I'm going to deep", or going deep is the right way of doing DDD?
Factories: Do I really need them? I can go ahead and write an static method within the domain object which knows more precisely how to construct it, am I doing wrong ?
Sorry for the long questions, but I'm feeling little lost despite of continues reading, if you can help me I would be glad.
I'll try to answer all your questions:
1.1. The only contact point the client can interact with the domain objects, the client should not be able to modify or create new Entities or value objects whiteout the aggregate root? (Yes/No)
Entities live within ARs and allowing the client to create them would violate encapsulation, so for entities you are correct, ARs create their own entities which don't get exposed to the outside (copies/immutable views could be).
On the other hand, value objects are generally immutable and therefore there's no harm in having them supplied to the AR as data inputs.
In general all modifications needs to go through the AR so that the AR is aware of the modification. In special situations the AR could detect modifications within it's cluster by listening to events raised by internal entities when it's impractical to go through the root.
1.2. Can an aggregate root contain only value objects ? for example User root, it contain only address, phone, things which are value objects as far as I understand. So is it a sign of bad design when your aggregate root contain only value objects? shall it contain only entities and via entities interact with value objects?
Favor value objects as much as you can. It's not unusual for all parts of an AR being modeled as values. However, there's no limitation or law stating whether or not an AR should have only values or entities, use the composition that's fit to your use case.
Entities: Shall the entities contain only value objects? or it can also contain other entities? can you give me a simple example please ?
Same answer as above, no limitation nor law.
Value Objects: shall I go ahead and encapsulate every primitive type in an value object? I can go deep and make every primitive type as an value object, for example: PhoneNumber can be a string or an value object which contains country code, number. the same thing can be applied to all other primitive type value such as name, email. So where to draw the line ? where to say "Ok I'm going to deep", or going deep is the right way of doing DDD?
Primitive obsession is worst than value object obsession in my experience. The cost of wrapping a value is quite low in general, so when in doubt I'd model an explicit type. This could save you a lot of refactoring down the road.
Factories: Do I really need them? I can go ahead and write an static method within the domain object which knows more precisely how to construct it, am I doing wrong ?
Static factory methods on ARs are quite common as a mean to be more expressive and follow the UL more closely. For instance, I just modeled as use case today where we had to "start a group audit". Implemented a GroupAudit.start static factory method.
Factory methods on ARs for other ARs are also quite common, such as var post = forum.post(author, content) for instance, where Post is a seperate AR than Forum.
When the process requires some complex collaborators then you may consider a standalone factory though since you may not want clients to know how to provide and setup those collaborators.
I'm new to DDD and I want to clearly understand each domain object structure and role
Your best starting point is "the blue book" (Evans, 2003).
For this question, the two important chapters to review are chapter 5 ("A model expressed in software") and chapter 6 ("the life cycle of a domain object").
ENTITIES and VALUE OBJECTS are two patterns described in chapter 5, which is to say that they are patterns that commonly arise when we are modeling a domain. The TL;DR version: ENTITIES are used to represent relationships in the domain that change over time. VALUE OBJECTS are domain specific data structures.
AGGREGATES and FACTORIES are patterns described in chapter 6, which is to say that they are patterns that commonly arise when we are trying to manage the life cycle of the domain object. It's common that modifications to domain entities may be distributed across multiple sessions, so we need to think about how we store information in the past and reload that information in the future.
The only contact point the client can interact with the domain objects, the client should not be able to modify or create new Entities or value objects whiteout the aggregate root?
Gray area. "Creation patterns are weird." The theory is that you always copy information into the domain model via an aggregate root. But when the aggregate root you need doesn't exist yet, then what? There are a number of different patterns that people use here to create the new root entity from nothing.
That said - we don't expect the application to be directly coupled to the internal design of the aggregate. This is standard "best practice" OO, with the application code coupled to the model's interface without being coupled to the model's implementation/data structure.
Can an aggregate root contain only value objects ?
The definition of the root entity in the aggregate may include references to other entities in the same aggregate. Evans explicitly refers to "entities other than the root"; in order to share information with an entity other than the root, there must be some way to traverse references from the root to these non-root entities.
Shall the entities contain only value objects?
The definition of an entity may include references to other entities (including the root entity) in the same aggregate.
shall I go ahead and encapsulate every primitive type in an value object?
"It depends" - in a language like java, value objects are an affordance that make it easy for the compiler to give you early feed back about certain kinds of mistakes.
This is especially true if you have validation concerns. We'd like to validate (or parse) information once, rather than repeating the same check every where (duplication), and having validated vs unvalidated data be detectably different reduces the risk that unvalidated data leaks into code paths where it is not handled correctly.
Having a value object also reduces the number of places that need to change if you decide the underlying data structure needs improvement, and the value object gives you an easily guessed place to put functions/methods relating to that value.
Factories: Do I really need them?
Yes, and...
I can go ahead and write an static method within the domain object
... that's fine. Basic idea: if creating a domain object from so sufficient set of information is complicated, we want that complexity in one place, which can be invoked where we need it. That doesn't necessarily mean we need a NOUN. A function is fine.
And, of course, if your domain objects are not complicated, then "just" use the objects constructor/initializer.
I am trying to learn some Core Data, and i have limited knowledge in general when it comes to databases (which i know Core Data is not, it's an 'Object Graph Manager') so i am in somewhat deep need of some help to figuring out what exactly i need to store, and where. I have three entities that i would like to create in my model:
Team
Player
GameResult
A team has the attribute teamName (string), but a team (in this case) should also have 4 players associated with it. This is where it already gets tricky for me to understand: How do i add/represent players (objects) as attributes within the Team entity?
The Player entity will for now only have an attribute of name as a string and preferably a unique ID(?) - to be able to keep track of individual results later on.
A GameResult however will have a few more attributes:
homeTeam
awayTeam
homeTeamScore
awayTeamScore
dateForPlayedGame
Both homeTeam and awayTeam i imagine should be an instance of a entity type Team which i also do not understand how i could represent. I'm guessing i will need to set up a few relationships as well: a team can have many players (4 in my case) and a player can belong to many teams (not the homeTeam and awayTeam in the same game though).
I would really appreciate some thoughts and guidance on how this model could be set up.
Edit: I should probably have an Entity of Game. Should i have this instead of GameResultand let the gameResult be an attribute of Gameor should i still have GameResultas an entity? What do you guys think? As i mentioned before: I have very limited knowledge about databases (in general)...as everyone can see.
How do i add/represent players (objects) as attributes within the Team entity?
You want to have a "one to many" relationship between Team and Players. Your model, when you create the one-may relationship, will automatically place an NSSet in your managed object that contains a list of players on the team.
The Player entity will for now only have an attribute of name as a string and preferably a unique ID(?) - to be able to keep track of individual results later on.
I know it sounds strange but don't worry about the unique ID. Core Data will handle that for you and you'll never miss it. You have to take this one on faith until you see it in action ;)
Both homeTeam and awayTeam i imagine should be an instance of a entity type Team which i also do not understand how i could represent.
I would probably think in terms of an attribute in the Team entity indicating "Home or Away". But there are other options if you don't like that one. I just think for for something that simple with only two possible values, this is probably the easy thing to do. There is nothing to prevent using the same entity for both.
Edit: I should probably have an Entity of Game. Should i have this instead of GameResultand let the gameResult be an attribute of Gameor should i still have GameResultas an entity? What do you guys think? As i mentioned before: I have very limited knowledge about databases (in general)...as everyone can see.
Not sure what the difference would be. Seems to me like a Game entity that included whatever the attributes are for "Game result" would make sense. A game always has a result and a result is always of a game. So, I don't see why you'd need both.
I don't want to say you're better off without general database knowledge, but you are almost. I had to forget just about everything I knew about SQL Server to be able to grasp Core Data.
The best thing I can say is that once "the light comes on" it will be simple and make perfect sense to you. My biggest problem was in having to unlearn a lot of what I knew about relational databases coming in.
Main thing I can say is remember that everything is about the managed object. You build your relationships into the model, and from then on you're dealing with NSSets of managed objects for the related entity.
Truthfully, it just makes too much sense to be easy to understand ;)
NOTE: One of the best things you can do is tinker with setting up the model, then generate your entity classes Editor | Create NSManaged Object Subclasses. Then study those classes and understand each of the relationship sets in them. That's what made things come clear to me, at least.
GLTY.
I´m a little confused about inheritance and relationships in core data, and I was hopping someone could drive to the right path. In my app i have created 3 entities, and none of them have (and are not suppose to have) common properties, but there´s gonna be a save and a load button for all the work that the user does. From my understanding I need to "wrap" all the entities "work" into an object which will be used to save and load, and my question is, do I need to create relationships between the entities? Because I have to relate them somehow and this is what make sense to me. Is my logic correct?
I'm implementing a budget calculator, and for the purpose of everyone understand what my issue is, I´m going to give an practical example and please correct me if my logic is incorrect:
Let´s just say you are a fruit seller, and because of that it´s normal to have a database of clients and also a fruit database with the kinds of fruit you sell. From my understanding I find two entities here:
Client with properties named: name, address, phone, email, etc.
Stock with properties named: name, weight, stock, cost, supplier, etc.
TheBudget with properties named: name, amount, type, cost, delivery, etc.
I didn´t put all the properties because I think you get the point. I mean as you can see, there´s only two properties I could inherit; the rest is different. So, if I was doing a budget for a client, I can have as many clients I want and also the amount of stock, but what about the actual budget?
I´m sorry if my explanation was not very clear, but if it was..what kind of relationships should I be creating? I think Client and TheBudget have a connection. What do you advise me?
That's not entirely correct, but some parts are on the right track. I've broken your question down into three parts: relationships, inheritance and the Managed Object Context to hopefully help you understand each part separately:
Relationships
Relationships are usually used to indicate that one entity can 'belong' to another (i.e. an employee can belong to a company). You can setup multiple one-to-many relationships (i.e. an employee belongs to a company and a boss) and you can setup the inverse relationships (which is better described with the word 'owns' or 'has', such as 'one company has many employees).
There are many even more complicated relationships depending on your needs and a whole set of delete rules that you can tell the system to follow when an entity in a relationship is deleted. When first starting out I found it easiest to stick with one-to-one and one-to-many relationships like I've described above.
Inheritance
Inheritance is best described as a sort of base template that is used for other, more specific entities. You are correct in stating that you could use inheritance as a sort of protocol to define some basic attributes that are common across a number of entities. A good example of this would be having a base class 'Employee' with attributes 'name', 'address' and 'start date'. You could then create other entities that inherit from this Employee entity, such as 'Marketing Rep', 'HR', 'Sales Rep', etc. which all have the common attributes 'name', 'address' and 'start date' without creating those attributes on each individual entity. Then, if you wanted to update your model and add, delete or modify a common attribute, you could do so on the parent entity and all of its children will inherit those changes automatically.
Managed Object Context (i.e. saving)
Now, onto the other part of your question/statement: wrapping all of your entities into an object which will be used to save and load. You do not need to create this object, core data uses the NSManagedObjectContext (MOC for short) specifically for this purpose. The MOC is tasked with keeping track of objects you create, delete and modify. In order to save your changes, you simply call the save: method on your MOC.
If you post your entities and what they do, I might be able to help make suggestions on ways to set it up in core data. You want to do your best to setup as robust a core data model as you can during the initial development process. The OS needs to be able to 'upgrade' the backing store to incorporate any changes you've made between your core data model revisions. If you do a poor job of setting up your core data model initially and release your code that way, it can be very difficult to try and make a complicated model update when the app is in the wild (as you've probably guessed, this is advice born out of painful experience :)
I'm working through a learning project around Core Data on OS X. I have an entity (Foo) in the data store, and in the UI, I use an NSArrayController with bindings to put some (name) field of the Foo objects into an NSTableView, where the user can add/delete/rename (and potentially reorder) the items.
As you know, Core Data storage is unordered. However, I'd like to give it order from the user standpoint. E.g. adding a new row to the table view fixes that new Foo to the end of the list, etc. If the table allows reordering, that order is maintained.
I assume that I should accomplish this by adding some hidden (ie the user never encounters it) "ordinal" field to the Foo entity, which is fine. I'm trying to figure out:
Where is the right place to set this "ordinal" field for new items? Right now, a button is invoking the add: action on the array controller and bindings handles all the rest magically. (I'll need access to the count of items to set it correctly.)
Where is the right place to fixup the whole result set's ordinals on delete or reorder?
Assuming all objects in the store have a reasonable ordinal attribute, what must I do to the UI connections to get the table view to display the results sorted by that ordinal? Is this something I can do purely with bindings? Do I need to subclass... something?
It feels like this is a common enough scenario that people here might have a ready answer. I'm new to Core Data and bindings-- trying to grope my way around. Don't need code; pointers in the right direction would be great. Thanks.
The simplest way to do ordering is to make sure that your entity closely models the data the user actually needs. Remember, Core Data is not a database system. It is an object graph management system with persistence options. Objects have behaviors. That means that you can put a lot more information into Core Data than you normally would for just a database.
A big part of the time, ordering comes naturally by good entity design. For example, the user needs to order Foo objects by when they were added to the graph. Therefore, the Foo object needs a creationDate attribute. Just bind a sort descriptor on the creationDate attribute and you are done.
The biggest challenge is arbitrary ordering that has nothing to do with data being modeled. I like to solve this issue with a lightweight Order entity that relates to the actual ordered entity.
Foo{
name:string
creationDate:date
order<-->Order.foo
}
Order{
foo<-->Foo.order
previous<-->Order.next
next<-->Order.previous
}
As you can see, the Order entities function like an old school linked-list. To insert a new Foo object in the order, just insert a new related Order object in between to existing Order objects. To create an ordered list, just start with Order object whose previous attribute is nil and then walk the next relationships, pulling each foo relationship as you pass.
There are other variations.
But again, entity design is always best. An entity is meant to model/simulate a real-world object, event or condition. If you think about the real-world thing you want to simulate and then include that in the entity and object graph design, then quite often your ordering occurs naturally.
Im new to working with Domain Models so forgive me for asking an elementary question.
If a Domain Object has a 1-many relationship with another Domain Object but logic that uses the first object works with only a subset of that objects related objects, what is the best way to expose this subset?
For example, say a Person is related to many Orders but some external logic needs to examine only the "Dispatched" Orders associated with a Person. Should the Person have a DispatchedOrders property, along with other properties for other subsets (such as CompletedOrders etc) or is this bad design? Assume for performance reasons I cant filter the objects in memory and must use SQL to pull back only the subset I'm interested in.
Thanks
If you're using SQL to find the set you're interested in, you're in a perfect world. Relational queries are all about finding that sort of thing. Find the perfect query, and then just figure out what the class of the result tuples are, i.e., an object for each result tuple, and process them appropriately.
In your example, you want a set of "Dispatched Orders", which whatever person information necessary attached to each one.
I think you have the right idea - DispatchedOrders would tell me precisely what collection of object you are returning to me. As Curt said, you are in good spot as you can use SQL / stored procedure to fetch your data.
One caveat - be sure that the domain matches the business process and is not an interpolation of you understanding of that process. That is - why does a person have primacy over an order and what corner are you painted into when you construct other objects. Does a line-item contain an order as well, and does this lead to object bloat? Discussions with your client should help shape the answer.
Rob Conery of SubSonic fame has a good discussion of these types of issues. It's worth listening to.