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 :)
Related
I want to start a project in JEE and I need to confirm about my class diagram. I need to know if the methods used are correct and if the composition I used is correct or not.
This is my class diagram:
The project is about an online sales store, that wants to set up a management tool to sell products, and to manage its products. This tool must include the following features:
Identification module: identification of clients, managers, supervisors
Sales module: make purchases for users
Product Management Module: Adding / Deleting Products
Statistical module: visualization of sales statistics
Functional Specifications
It is necessary to act on the application, to connect to the application with a user ID and password. To facilitate its use and in order to avoid any mishandling thereafter, here is the solution:
User Profile:
The user will be able to visualize the products sold by My Online Races. The user can place an order, provided that he has registered with the site My Online Races.
Manager profile:
The manager will be able to manage the products:
Add / Edit / Delete Products
Add / Edit / Delete category
These data insertions can be made using CSV or XML files, but also through various forms on the website.
The manager will be able to view the sales statistics.
Supervisor Profile:
The supervisor can add managers whose roles are specified above.
The supervisor will be able to view the sales statistics.
The supervisor will be able to view all the actions performed by the managers, a sort of audit trail.
Well I wish to know already if you have remarks about my design. As well as I have a confusion for several methods, for example adding, modifying and deleting a product. Should I put them in the manager or product class? Is the composition I put correct or should I remove it?
Quick review of the diagram and advices
First some minor remarks about class naming: Ordered should be called Order.
The composition between Article and Order is just wrong (not from a formal view, but from the meaning it conveys). Use a normal one-to-many association: it would reflect much better the real nature of the relation between the two classes. Please take into account that a new article may exist without having been ordered, so it shoud be 0..* instead of 1..*
+belongs and +do in the middle of an association are syntactically incorect. You should use a plain triangle instead (or nothing at all). The triangle should be oriented in the reading direction Person do |> Order and Article belongs to |> Category
The methods seem ok. You do not need to add a suffix.
How shall objects be managed (created/updated/deleted) ?
A more advanced concern is not about the diagram but about how you want to organise persistence (i.e. database storage):
do you really want the object to be an active record, that is an object that adds, updates and deletes itself (to the database) ? It's simple to set up, works well, but makes the class dependent on the underlying database implementation and thus makes maintenance more difficult;
or wouldn't it be better to use a repository for each object ? In this case the repository acts as a collection that manages all the database operations. The domain object (Article, order, User, ...) then have nothing to know about the database, wich leads to more maintainable code.
But this is a broader architectural question. If it's just for a first experimental project with JEE, you can very well use the active records. It's simpler to set up. Be sure however in this case to disambiguate the Add/Update/Delete on Person, since it currently may give the impression that any person can add anyone.
Improvement of the model
A final remark, again not about the diagram itself, is about the domain. Your model considers that an Order is about a single Article.
In reality however, orders are in general about one or several articles: if this would also be the case here, your Order would become an OrderItem and the real Order would be inserted between Person and OrderItem. You could then make the relation between Order and OrderItem a composition (i.e: OrderItem is owned by Order, which has responsibility for creating its items, and the items have no sense without the related order).
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've got a data model where there is a Person entity, which has a transformable attribute which is an array of dictionaries containing information. The model is much bigger than that, this is just the part I'm having trouble with. It was designed this way by an old developer, and in taking over the project I need to migrate this to be 100% core data.
So what I need to do is create a new entity, then step through each dictionary in the Person's array and create new instances of that entity with the information from that dictionary. I thought I could use an NSEntityMigrationPolicy to set up a custom migration for this new Entity, but it seems the Core Data migration is expecting X number of source entities to translate to X number of destination entities. Because I technically have 0 source entities right now (because they're in an array that Core Data doesn't really know anything about), I'm not sure how I can make the migration create new entities during the process.
What, or rather where in the migration procedure, is the best way to do what I'm trying to accomplish? I've always used lightweight migration in the past, so this is my first adventure in custom migration.
It would help to have a sense of your data model (schema) - but let's assume that your Person entity now holds home address and list of favorite restaurants. And let's further assume that you will be creating new entities Address and Restaurant along with the following relationships:
Person has one Address, so there's a to-one relationship from Person to Address called "homeAddress". There's an inverse to-many relationship from Address to Person, because many people could live at the same address.
Person has a to-many relationship (called restaurants) to Restaurants. Restaurant could also has a to-many relationship to Person (though this might be one of those cases where bidirectionality doesn't really make sense).
Anyway, the point is that now - in addition to your PersonToPerson NSEntityMigrationPolicy subclass, you will also have PersonToAddress and PersonToRestaurant. These will be the places that you unpack the old data and use it to instantiate and initialize new Address and Restaurant objects.
Of course, there are lots of other complicating issues. For example, you won't want to be creating a new instance of the same Restaurant for every Person who likes it. You will need to keep track of newly created Restaurants.
You will want to order your mappings strategically - probably with PersonToPerson first.
You might want to look at Marcus Zarra's Core Data sample code and maybe even buy his book.
I'm working a pretty standard e-commerce web site where there are Products and Categories. Each product has an associated category, which is a simple name-value pair object used to categorise a product (e.g. item 1234 may have a category "ballon").
I modelled the product as a root aggregate, which owns and knows how to modify it's category, which is an entity.
However, I ran into a problem where a user needs to be able to search a category. How am I supposed to implement this in DDD? I'm new to DDD but I believe that only root aggregates should be given it's own repository. So that leaves me with 2 options:
Add "SearchCategory" method to the ProductRepository
Implement the search logic as service (i.e. CategoryFinderService)
I personally think option 2 is more logical but it feels weird to have a service that touches database. Somehow I feel that only repository should be allowed to interact with database.
Can someone please tell me what's the best way to implement this?
IMHO, in your Domain Model, Category should not be child of the Product Aggregation. The Product has a Category, but it does not know how to create or edit a Category.
Take this another example. Imagine the ShoppingCart class, it's an aggregate root and contains a list of Items. The ShoppingCart is responsible for adding/editing/removing the Items, in this case you won't need a Repository for the Item class.
Not sure by the way, I'm new to this just like you.
Placing something You don't know where to put into artificial services usually leads to anemic domain model.
I would go with first option. But need for entities without context of root is a sign that You might lack another root.
Don't try to implement everything with your domain model. The domain model is powerful for changing the state of the system, but unnecessary complex for querying. So separate the two. It's called Command Query Responsibility Segregation, or CQRS. And no, it has nothing to do with Event Sourcing, even though they do work nicely together.
I implement scenarios such as this so that I have a domain logic side with the domain objects and repositories (if needed), which do the state changing when something happens, i.e. new order is placed or order is shipped. But when I just need to show something in the UI, for instance the list of the products filtered by the category, it is a simple query and does not involve the domain objects at all. It simply returns Data Transfer Objects (DTO) that do not contain any domain logic at all.
This is only an example.
Say that you have 2 entities for 2 different context boundaries. The first context is the SkillContexter, the entity is 'Player' and has 3 properties: Id, Name and SkillLevel. In the other context (Contactcontext) the entity is 'Player' and has 3 properties: Id, Name and EMail.
How do I persist these entities to the database? I only want one table (Player) and not two tables (PlayerContact, PlayerSkill). Shall I have two different repositories for player that save the different context-entities, but into same table? Or shall I have a "master" player entity that holds all properties that I need to save, so that I create a new entity called PlayerMaster that has 4 properties: Id, Name, EMail and SkillLevel?
The first solution gives me more repositories, and the second makes me make a "technical" entity that only purpose is to save data to a database, and that feels really wrong, or is there a better solution that I have missed?
How have you guys solved it?
When I first started with DDD, I also wrestled with the Context + Domain + Module + Model organization of things as well.
DDD is really meant to be a guide to building your domain models. Once I stopped trying to sub-organize my Contexts and boundies, and started thinking of what really is shared between entities - things started to fit together better.
I actually do not use contexts, unless it is a completely different application (app = context). Just my preference. But, I do have Modules that only share base abstracts and interfaces common throughout code (IRepository, IComponent, etc). The catch is, DDD says that Modules can share entities between modules - but, only on a very limited scale (you really don't want to do it often).
With that in mind, I would get away from using contexts and move to a "what really am I trying to accomplish, what do these models have in common). Here's what I would think, reading your question (if I understand them).
Person() is a base entity. It has ID and Name.
PlayerSkill() is a Value Object, that is
accessable from Person().PlayerSkill.
Contact() is an entity that inherits Person(),
so it inherits ID and Name, and has additional Contact properties you want.
Now, I just tore up your domain. I know.
You can use a hybird approach as well:
Person() is a base entity. It has ID and Name.
Player() inherits Person(), applies Skill()
and other VOs.
Contact() inherits Person(), applies Address()
and other VOs.
I'm not quite sure what you mean by context boundaries, so my answer may be off.
Do the two Player entities represent the same physical entity (person)? If so, then I would create a single Player entity with all four attributes and store their data in a single table.