How do you call a NSManagedObject that is no longer a fault? - core-data

This might seem a stupid question, but I always want to use a quick word just as I use for 'fault' NSManagedObject instances. Once the fault was fired... how should we call these objects? From http://commandshift.co.uk/blog/2014/04/24/its-not-your-fault/ I can see Apple would call this a 'fully realized NSManagedObject'. I really don't like that.
Is there an official way of calling these objects? If there is, then this question is not subjective and I'll choose the correct answer. If there's not, this question should be closed, since there probably wouldn't be a correct answer.

In our book we call them materialized as in “fully materialized object” or “turning an object into a fault or materializing it causes any KVO observers to trigger”.

Related

How would I make separate duplicated logic in Value Objects

I'm learning DDD (Domain Driven Design) and reading Clean Architecture. I found out about Value Objects and have been reading more about them and have implemented some in my application which could be found https://gist.github.com/Tyler0722/73ec826be814b8e54b9f6ae6ae836409.
Value Objects are created by calling the factory method which performs validation and follows the separation of concerns principle. The problem is I have two Value Objects where the validation logic is duplicated. Username and QuizTitle where the only difference is MAX_LENGTH which violates the DRY principle. I was wondering if anyone knew anyway I could make this DRY.
If you want to remove repetition you must be very careful.
The first question you should ask yourself is
What is the same and what is different?
Maybe you will find the same or similar structure like
check the props
create an error result or a success result
If you found out what you think the same is you have to ask yourself more questions:
Do the things that are (look) the same have different responsibilities?
Do they change for the same or for different reasons?"
These are the questions that are about the single responsibility principle. Sometime things look the same by accident. They look the same but are different, because they change of different reasons. If you eliminate the "duplication" in this case you will have more problems then you solve.
E.g. if you consolidate the validation logic of QuizTitle and Username into one method and later you get a change request for the QuizTitle validation you can easily break the validation behavior of Username. I guess it should not change if the QuizTitle validation changes.
You might also want to read the good article by Martin Fowler about Avoiding Repetition
My suggestion is to not do it. In this case it's just not necessary.
But if you want to do it anyway, you can build a Validation class with static functions. At my work we use Webmozart/Assert and if you take a look at its implementation you will understand what I mean. In my opinion there are very handy. Also you can pass the MAX_LENGHT as an argument.
Well, I agree with Darius Mann, that these value objects have similar business logic is ocasional, if they are different concepts in your app, keep them separated and independently, it is my opinion.

UML and Implementation: Associating Classes through IDs

I was recently studying an online course. it was recommended that to reduce coupling we could simply pass the ID from the customer object to the Order object. that way the Order did not have to have a full reference to the Customer class.
The idea certainly seems simple and why pass a whole object if you don't need all its attributes?
1) What do you think of this idea?
2) How would I express the relationship between the Customer class and the Order class in UML if only an ID is passed. This isn't just an example of aggregation is it? Doesn't composition and aggregation require more than just passing a value?
Thanks!
First of all you need to be clear about what UML actually is. On the one hand you have an idea and on the other side there is some code running on hardware. Ideally the latter supports the first in a way that brings added value to a user of the idea. Now, there are many possibilities to describe the way from idea to code. And UML is one of them. It is possible to describe each step on this way but for pragmatic reasons UML stops at the border of code, namely programming languages.
Now for you concrete question: Any object can be seen as an instance. That is some concrete memory partition with a fixed address. Programming languages realize instances by allocating memory and using the start address as reference. And since this reference does not change the object can be identified by its address. Clearly then, an association will just be the a pointer. And an association class will hold two (or more) such pointers.
Honestly, the very first time I started with OO I was also confused and thought that it's a waste of resource to pass those large objects. But since it's just a pointer it's really easy going.
Again, things can get more difficult if you need to persist objects. In that case you need an artificial key you can save along with the object and you will likely need tables to map artificial key to the concrete instance address.
The answer to this question depends on a number of factors, which I started listing in a comment attached to your question. I will assume that you are either using UML to create a Domain Model, or you are describing an implementation done using a statically typed language.
If you are using UML to create a Domain Model, you are obfuscating the semantics when you use an ID to "link" classes. Just draw and annotate the association and you're done.
If you are describing an implementation done using a statically typed language - types exist for a reason. Using generic IDs to link things means that the information that the system needs most become more indirect, and therefore more opaque (which is bad). In your case, the Order object still must acquire a typed reference to a Customer object to do anything with it.
For example, the Order may acquire a reference to the Customer by invoking a lookup by the ID, but it must cast the reference to an appropriate type to invoke anything on the Customer object. So you haven't reduced the coupling from the Order to the Customer. You just buried it somwhere else.

Can I skip operations in nested contexts?

Before nested contexts my life was easy declaring some common functions from NSManagedObjects such as:
awakeFromFetch
awakeFromInsert
validateX
didChangeValueForKey
Through try and fail, call it, life lessons. I learnt to be more careful about those functions when using inheritance with my entities.
Now jumping to the nested context part of Core Data, I am getting used to see the very same NSManagedObject existing in several contexts. I am trying to grasp a key part of this: The above mentioned functions might be called several times from different contexts, but things like validation, value observation, and initialization are only relevant once. Therefore I normally check if the self.managedObjectContext correspond to the main context I work with. If they are the same, I run the whole function, if not, I just call [super] and return.
Is that the way I am supposed to deal with nested contexts?
Doing this has saved me several times. I was surprised seing awakeFromInsert called more than once for the same object, but even if I abort the initialization part of that function in all contexts but the main one, the information is persistet back to the store. I would like some confirmation that I am dealing with this topic the right way.
UPDATE:
Trying to make my ideas clear I wrote a post about this topic in my blog. What I wrote there has saved me several times from invalid entity layouts and other errors. However I am not sure if there are approaches better than mine.
http://www.digital-lumberjack.com/blog/2012/11/surviving-core-data/

How is a delete of an aggregate root handled in DDD?

I have two an aggregate root referencing another aggregate root (first references the second via the identity of the second aggregate root).
A command from my application layer (via MVC asp.net) now deletes my second aggregate root.
At the point of deleting the root, do I send a Domain Event telling the first aggregate root to "NULL" the reference to the second aggregate which now does not exist?
JD
You're going about it the wrong way. Step back from the technical issue you are facing. First of all I doubt there is such a thing as "Delete" in your ubiquitous language. Most likely people will call it "archive", "taking out of order", "remove", "out of stock", ... some term that denotes that a particular aggregate is at the end of its life-cycle. When domain experts speak of such things, this should be a trigger for you to ask them a question along the line of : "Well if you discontinue a Product, how will that affect a Promotion for that particular Product?". To correlate back to your issue: Promotion being the aggregate that holds a reference to the Product aggregate. So it very much becomes a business issue rather than a technical one. Most of the time business people already have a process in place that prevents this technical issue from happening in the first place (e.g. you can't discontinue a Product that's being used in a Promotion). I hope it's clear by now that giving you a generic answer is not an option.
I think the question was not actually answered by another responder that has been here for a while. I also think that those who come here deserve an answer. I will answer the question (see #2), but let me first clarify something.
#1 Why Not Delete?
So, first, I agree with another answer and will say that in domain terms, there is no such thing as deletion typically. I like the angle from which this article by Udi Dahan explains the point.
My explanation for being against the deletion is a bit old-style, simpler (yes, even simpler), and hopefully easier to understand. Imagine a world without (or before) computers. People did everything on paper. Imagine (I know it might be awkward) that you are dealing with a book instead of the video. A book that contains the same info as the video you are deleting. You can't delete the book, but you can "burn" it or "trash" it. It actually continues living but changes its form of existence. Similarly, your video moves from its current state to the next state, or maybe it even transforms and gives birth to the object that is its next state. Anyway, the point is, you are changing the state and not deleting it. So, it would be best if you modeled it as a state change. That was the point, although I know it could have been unclear.
#2 How to Update Other Aggregates?
Very simple, the original aggregate (the one that changes state, see above) dispatches an event that describes what happened to it. You subscribe to that event, and the event handler updates other impacted aggregates. I think this was the answer you were looking for without all the "can't delete" conversations. Sorry that I added that part again, but I wanted to clarify both points for readers.
To expand the book's example: when you trash the book, you need to update the book directory (or index paper that shows where each book is in the library), not to mention the trashed book anymore. So without computers, the one who trashed the old book would tell the other guy responsible for the directory to scratch the book from the list (read as "when the book is trashed, the directory must remove it from the list"). That is what the event accomplishes but in digital terms.

Doubts About Core Data NSManagedObject Deep Copy

I have a situation where I must copy one NSManagedObject from the main context into an editing context. It sounds unnecessary to most people as I have seen in similar situations described in Stackoverflow but I looks like I need it.
In my app there are many views in a tab bar and every view handles different information that is related to the other views. I think I need multiple MOCs since the user may jump from tab to tab and leave unsaved changes in some tab but maybe it saves data in some other tab/view so if that happens the changes in the rest of the views are saved without user consent and in the worst case scenario makes the app crash.
For adding new information I got away by using an adding MOC and then merging changes in both MOCs but for editing is not that easy. I saw a similar situation here in Stackoverflow but the app crashes since my data model doesn't seem to use NSMutableSet for the relationships (I don't think I have a many-to-many relationship, just one-to-many) I think it can be modified so I can retrieve the relationships as if they were attributes
for (NSString *attr in relationships) {
[cloned setValue:[source valueForKey:attr] forKey:attr];
}
but I don't know how to merge the changes of the cloned and original objects. I think I could just delete the object from the main context, then merge both contexts and save changes in the main context but I don't know if is the right way to do it. I'm also concerned about database integrity since I'm not sure that the inverse relationships will keep the same reference to the cloned object as if it were the original one.
Can some one please enlighten me about this?
Wow, lots of questions and randomness in this one. First, you do not need to add comments to your own question, better to edit the question itself.
Second, you don't need multiple NSManagedObjectContext instances if you are running a single threaded application. Your entire application can easily run off of a single instance. Multiple contexts are for rare edge cases and multi-threading situations.
By using a single context it will resolve all of your issues with your attempts to clone. However, if you are still wondering how to do a deep copy of a NSManagedObject you can get some guidance from the example code in my book at The Pragmatic Programmers; the source code of which is free to download.
Update
All NSManagedObjectContext instances are "editing ones". You only need a single context per thread. You can easily ask the context for the non-inserted entities if you want to delete them before a save and you can easily save entities as they are changed. Except for some extreme edge cases you do not need a second context.
Update
You are still creating more work for yourself then you need to. You don't need to save an object for the view to go away. You can leave as many objects as you want in an unsaved state in the context.
You are going to spend more time debugging dealing a deep copy of objects than it is worth with the design you are describing. If you are going to use more than one context, make sure they are attached to the same NSPersistentStoreCoordinator so that you don't need to copy the objects around, you can just save the "secondary" context and then catch the save notification in the main context.

Resources