Efficiently pass core data objects to common detailViewController - core-data

I have a number of entities that describe different pieces of equipment.
I read these into the EquipmentViewController.
I'm struggling to figure how to use a generic EquipmentDetailViewController that can be used to show and update any of the different entities.
I have it working by having a separate DetailController to manage the details of each entity, but there has to be a better method.
I could possibly merge the entities, but I think that would be unwieldy.
If I could name a variable to hold any entity, I would be set. Is that possible (or correct)?
This must have come up before but I could not find an answer that I understood. If there is one, please point me to it, and I'll close this question.
TIA

Related

DDD: Referencing non aggregate roots

I'm trying to improve my design using some DDD concepts. Currently I have 4 simple EF entites as shown in the following image:
There are multiple TaskTemplates each of them storing multiple TasksItemTemplates. The TaskItemTemplates contains various information (description, images, default processing times).
Users can create new concrete Tasks based on a TaskTemplate. In the current implementation, this will also create a TaskItem for every TaskItemTemplate, but in the future it might be possible to select one some relevant TasksItemTemplates.
I wonder how to model this requirement in DDD. The reference from TaskItem to TaskTemplateItem is not allowed, because TaskTemplateItem is not an aggregate root. But without this reference it is not possible to get the properties of the TaskTemplateItem.
Of course I could just drop the reference and copy all properties from TaskTemplateItem to TaskItem, but actually I like the possibility to update TaskItems by updating the TaskTemplateItems.
Update: Expected behaviour on Task(Item)Template updates
It should be possible to edit TaskTemplate and TaskItemTemplate and e.g. fix Typos in Name or Description. I expect these changes to be reflected in the Task/TaskItem.
On the other hand, if the DefaultProcessingTime is modified, this should not change the persisted DueDate of a TaskItem.
In my current Implemenation it is not possible to add/remove TaskItemTemplates to a persisted TaskTemplate, but this would be a nice improvement. How would I implement something likes this? Add another entity TaskTemplateVersion between TaskTemplate and TaskItemTemplate?
Update2: TaskItemTemplateId as ValueObject
After reading Vaughn's slides again, I think with a simple modification, my model is correct according to DDD:
Unfortunately I do not really understand, why this Design is better (is it better?). Okay, there won't be unnecessary db queries for TaskItemTemplates. But on the other side I almost ever need a TaskItemTemplate when working with a TaskItem and therefore everything gets more complicated. I cannot any longer do something like
public string Description
{
get { return this.taskItemTemplate.Description; }
}
Based on the properties that you list beneath TaskItem and TaskItemTemplate I'd say that they should be value objects instead of entities. So if there isn't a reason (based on the information in your question there isn't) to make them entities, change them to immutable value objects.
With that solution, you just create a TaskItem from a TaskItemTemplate by copying its data.
Regarding the update scenario that you describe, it see the following solution:
TaskItems are created from a specific version of the TaskItemTemplate. Record that version with a TaskItem.
The TaskTemplate is responsible for updating its items and keep track of their version.
If a template changes, notify all Tasks that are derived from the template if immediate action is required. If you just want to be able to "pull in" the template changes at a later time (instead of acting when the template changes), you just compare the versions.
To make informed decisions, it is very important that you fully understand the pros and cons of immutability. Only then you will see a benefit in modelling things as value objects. One source on the topic that I find very valuable is Eric Lippert's series on immutability.
Also, the book Implementing DDD by Vaughn Vernon explains the concepts of value objects and entities very well.

Core Data Inheritance and Relationships

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 :)

How to go about creating an Aggregate

Well this time the question I have in mind is what should be the necessary level of abstraction required to construct an Aggregate.
e.g.
Order is composed on OrderWorkflowHistory, Comments
Do I go with
Order <>- OrderWorkflowHistory <>- WorkflowActivity
Order <>- CommentHistory <>- Comment
OR
Order <>- WorkflowActivity
Order <>- Comment
Where OrderWorkflowHistory is just an object which will encapsulate all the workflow activities that took place. It maintains a list. Order simply delegates the job of maintaining th list of activities to this object.
CommentHistory is similarly a wrapper around (list) comments appended by users.
When it comes to database, ultimately the Order gets written to ORDER table and the list of workflow activities gets written to WORKFLOW_ACTIVITY table. The OrderWorkflowHistory has no importance when it comes to persistence.
From DDD perspective which would be most optimal. Please share your experiences !!
As you describe it, the containers (OrderWorkflowHistory, CommentHistory) don't seem to encapsulate much behaviour. On that basis I'd vote to omit them and manage the lists directly in Order.
One caveat. You may find increasing amounts of behaviour required of the list (e.g. sophisticated searches). If that occurs it may make sense to introduce one/both containers to encapulate that logic and stop Order becoming bloated.
I'd likely start with the simple solution (no containers) and only introduce them if justified as above. As long as external clients make all calls through Order's interface you can refactor Order internally without impacting the clients.
hth.
This is a good question, how to model and enrich your domain. But sooo hard to answer since it vary so much for different domain.
My experince has been that when I started with DDD I ended up with a lots of repositories and a few Value Objects. I reread some books and looked into several DDD code examples with an open mind (there are so many different ways you can implement DDD. Not all of them suits your current project scenario).
I started to try to have in mind that "more value objects, more value objects, more value objects". Why?
Well Value objects brings less tight dependencies, and more behaviour.
In your example above with one to many (1-n) relationship I have solved 1-n rel. in different ways depending on my use cases uses the domain.
(1)Sometimes I create a wrapper class (like your OrderWorkflowHistory) that is a value object. The whole list of child objects is set when object is created. This scenario is good when you have a set of child objects that must be set during one request. For example a Qeustion Weights on a Questionaire form. Then all questions should get their question weight through a method Questionaire.ApplyTuning(QuestionaireTuning) where QuestionaireTuning is like your OrderWorkflowHistory, a wrapper around a List. This add a lot to the domain:
a) The Questionaire will never get in a invalid state. Once we apply tuning we do it against all questions in questionaire.
b) The QuestionaireTuning can provide good access/search methods to retrieve a weight for a specific question or to calculate average weight score... etc.
(2)Another approach has been to have the 1-n wrapper class not being a Value object. This approach suits more if you want to add a child object now and then. The parent cannot be in a invalid state because of x numbers of child objects. This typical wrapper class has Add(Child...) method and several search/contains/exists/check methods.
(3)The third approach is just having the IList exposed as a readonly collection. You can add some search functionality with Extension methods (new in .Net 3.0) but I think it's a design smell. Better to incapsulate the provided list access methods through a list-wrapper class.
Look at http://dddsamplenet.codeplex.com/ for some example of approach one.
I believe the entire discussion with modeling Value objects, entities and who is responsible for what behaviour is the most centric in DDD. Please share your thoughts around this topic...

Displaying different NSManagedObject entities in the same NSOutlineView

Basically I have three different Core Data entities (A, B, C) and A contains a set of Bs and B contains a set of Cs. These three entities are, however, quite different from each other and they don't have common methods to access each other's children or the values to be displayed in the view.
I'm trying to display these three enties in an NSOutlineView. There's propably other solutions too but I came up with two different ones:
Implementing NSOutlineViewDataSource protocol and handling each of the entities differently.
Consolidate the classes with categories and add common (transient) methods/properties for the NSOutlineView to use. These methods/properties get their actual values from the model entities' properties.
I chose the second option and added getters for the children and the display value. This way, however, the Key-Value Observing does not work anymore and changes in the model are not reflected to the view. I understand why, but I'm not sure how to solve this the right way. I was thinking of some way to be notified of the actual model value changes and forward them to the view.
Is there any easy way to forward those notifications or should I consider some other alternative?
In short, I need to display different kinds of entities in an NSOutlineView and I don't want to mess the model.
Can't you just use relationship A->B->C to fetch the object A and display them in outline view?
After some trial and error, I found out that creating a custom data source is really that simple and decided to go with the first choice. Also, with drag & drop support this feels much more natural way.
The only issue was with outlineView:setObjectValue:forTableColumn:byItem: for which one needs to specify column identifier references. I feel that undirect dependencies are always something one should avoid, but this is a small matter in comparison to making this work nicely.

DDD: Organizing 100s of properties on an Entity

How would you organize an entity that has 100s of properties? One could go as far to say 100s of properties, with a few Value Objects (as a few of the properties have 2 or 3 properties of their own). But the point is, how to handle the large number of properties.
I am re-creating our model from the ground-up using DDD, and the current issue is how to organize one of main entities that is broken up into many many many subsets. Currently it was written to have about a dozen sub-sets of properties. Like CarInfo() with 50+ properties, CarRankings() with 80+, CarStats(), CarColor(), etc, etc.
Think of it as mass-data stored on a single entity root.
Is it appropriate to have a service for the simple purpose of grouping a large collection of properties? Like CarInfoService that would return a Car() object, along with a large collection or sort.
Another idea would be to look at how the data is displayed. There is no one view that shows all of this data. Instead, they are split up based on their subjective matter. Like CarInfo shows all information about the car. Another would be CarStats that shows all stats of the car. So in this sense, the Application layer can build the underlying details needed for the UI. But, I still need a way to store it in the domain.
I have a mind to just put a number of xml property bags on it and call in the day. lol
This is a tough problem. You've got an aggregate root with lots of branches. But it sounds as if your users only work with certain collections at certain times. You could try pruning the tree a bit.
For instance, in your Car example, if your users are comparing the rankings of different cars, you could treat that as its own module or subsystem. No need to load up the detailed car data associated with each ranking, if the specific task is to figure out which ones rate better than others.
Remember, even though the data may be stored in a parent-child hierarchy in the database, it doesn't necessarily mean your domain will be structured in the same way.
By looking at the tasks or functions your users will perform on your data, you might discover concepts that help to break up that giant aggregate into more manageable chunks.
If you do need to assemble the full root with all of its branches, I think you'll definitely want some sort of service to bring everything together.
I think you should consider to split such an entity in different bounded contexts related via shared idenfitiers. Thus you will have different Cars in different BCs (thus different namespaces, too), and each one will handle only the informations that are related to that particular aspect.
This way, in case of deeper insight, chances are that you will have to refactor only a BC without affecting the others.

Resources