So I recently switched from Unity to Unreal and I cant understand the concept of Owner in Unreal.
I understand parent-child relationships but what exactly is an owner? Changing the owner of an actor does not change it's hierarchy so how exactly is unreal handling ownerships?
Thank you in advance.
EDIT: Removed rendering related detail that I found is not a good use case for ownership.
There are several types of "parent-child" relationships that are frequently used in Unreal in context of UObjects, and which don't necessarily have to be the same (i.e. the same object can have three different "parents" in the different realtionships).
One is transform attachment (only relevant for actors), where an actor which is "attached" to another actor (its "attach parent") inherits transforms before applying its own.
Another one is object-lifetime parent-child relationships, where each object has an "outer", and if an object's outer is removed (garbage collected etc.), so is the object. For AActors, by default that's the ULevel they are in, so it's not so important.
The third one (again only relevant for actors) is the ownership relationship, which have some interesting properties. For one, if an actor's owner gets Destroy-ed, so does the actor. For example:
// Make an owner actor
AActor* Parent = GetWorld()->SpawnActor<AActor>();
// Make an owned actor
FActorSpawnParameters SpawnParameters;
SpawnParameters.Owner = Parent;
AActor* Child = GetWorld()->SpawnActor<AActor>(AActor::Static_Class(), FTransform(), SpawnParameters);
// Destroy the owner
Parent->Destroy();
// After this, the Child actor is also destroyed
Another property of this relationship has to do with replication. Properties such as bOnlyRelevantToOwner, as well as conditional property replication such as COND_OwnerOnly, COND_SkipOwner rely on this. Property replication is a very big topic that won't fit in the scope of one answer, but the linked page of UE documentation can help.
All in all, it's important to note: actors don't necessarily have to have an owner, and unless you need the owner to be set for a specific reason such as the aforementioned functionalities, it's standard practice not to set one.
Related
Example: there are objects A and B. Object A must connect with object B (by Script) and object B must connect with object A (by Script).
How to do it more properly:
Create Scripts for each objects.
Create Empty Object and add one Script to it, and then in this Script to create two references (for A and B)?
What you describe at section 2 is known as Mediator pattern. You should definitely use it or you can also use Observer pattern. The difference between them is there's a mediator between them which causes loosely coupling.
The common part between them is whenever an event happens to the object itself, it throws a callback and the other objects gets notified and do their own jobs.
To even make a better organization you can look at MVC(S) and ECS architectural pattern.
I have a problem with the boundaries of aggregates. I was trying to read about aggregates, aggregate roots, and boundaries, looking for some code examples but I still struggle with it.
The app that I'm working on is an app to manage architecture projects.
Among the screens in the app there will be a screen with all details for the selected project, and one with all jobs for the selected constructor.
I have one AggregateRoot - ArchitectureProject.It has an Architect, Stages, etc. and it has a list of ConstructorJobs (as it has to be on the screen with project details). ConstructorJob has its name, some value, and a Constructor. A Constructor can have some ConstructorType. As for me, Constructor is another AggregateRoot. I have a problem with ConstructorJob. Where should I place it? What should be responsible for managing it?
I was trying to thing what cannot exist with what, and ConstructorJob cannot exists without Project, but on the other hand it has to have Constructor as well...
I can't imagine that Constructor would belong to Project Aggregate, as ConstructorType would be 4th level child to id, so searching for all constructors of that type would be painful, wouldn't be?
I would appreciate any explanation, how to handle such cases.
I think you are missing an important rule which usually makes your life a lot easier:
Rule: Reference Other Aggregates by Identity
See also Vaughn Vernon's Book Implementing Domain-Driven Design, chapter 10 - Aggregates.
It is important to note that Aggregates in the sense of domain-driven design are not so much focused on if the existence of one aggregate makes sense without the other. It is more about transactional boundaries. So an aggregate should create a boundary around elements that should only change together within the same transaction - to adhere to consistency.
So I guess, that you will change your Project in different use cases you would change the Constructor - which I guess can be referenced in different projects.
This means you should reference other aggregates within aggregates only by id which avoids modelling huge aggregates with deep hierarchies. It also means that if your aggregates tend to grow bigger over time that you might have missed some new aggregate which you initially modelled as entity and should be an aggregate on its own.
As for me, Constructor is another AggregateRoot. I have a problem with ConstructorJob. Where should I place it? What should be responsible for managing it?
In your case I would model it the following way:
The ConstructorJob is a Value Object which holds some data (name, etc.) and also a reference to a Constructor aggregate. But this reference is not a reference in terms of object reference like you would do it with a child entity of an aggregate root. The constructor aggregate is referenced by an identifier (UUID, integer or whatever you are using as id type) in the ConstructorJob.
The ConstructorJob value object would be part of the Project aggregate. The project aggregate could of course directly hold the id of the constructor aggregate but I guess in your case the value object might fit quite well.
I am trying to set up multiple DbContext objects in my solution. One will be the initialization context and the others will be bounded contexts.
The scenario I am having difficulty resolving is as follows:
Having two database tables, a parent object and a child object. Upon initialization the tables are created okay with all the properties on, however in the bounded context I want to use the parent object and only return a subset of properties from the child object.
At the moment both the initialization context and the bounded context use the same parent class so therefore I can't use a third info object for the child object in the bounded context.
Would I therefore need to create another parent object for use in the bounded context which uses another child object with subset of properties?
So would I need in the initialization context a parent and child object and in the bounded context a separate parent and child object where the child object only has a subset of properties and the parent object points to that child?
I am quite happy to create the child class with a subset of properties but it seems a bit long winded to create a separate parent object to point to the child info object but I can't see a way around this.
Having watched Julie Lermans TechEd Europe 2014 "Entity Framework Model Partitioning in Domain-Driven Design Bounded Contexts" https://www.youtube.com/watch?v=rGA_FNew-6g I have decided to go down the route of having a master context purely for database migrations.
I found the idea of using events and message queues and separating the data into different tables in the database interesting but it's probably a bit heavy handed for our needs at the moment.
So I'm new to the concept of routed events, but I know that messages are flying everywhere when fields are changing via the RaiseDataMemberChanging / RaiseDataMemberChanged messages.
The quick question is how to I "listen" for those routed messages?
I would like my view model, in a MVVM correct matter, intercept a message that a field is being updated, deep down in the heirarchy of tables. If a change occurs in a child (a date range), that date range change has some business logic associated with it that works from top down.
I've know that I can use partial methods to inject code during the changing and changed events, but the design (one to one relationship) means that a change to the child, in the context of the child, has no reference the parent (Parent has a one to one reference to child, but child has no reference to parent).
Yes I can add the reference from the child to the parent (making the parent have both a one to one, as well as a one to many relationship), but during creation of the entity, this creates a problem - parent has to exist before the child entity exists, and the child entity has to exist before a reference to the parent can exist. This design requires an insert of the parent, and child, then an update of the child - which confuses WCF RIA Services during the inital creation process.
Sorry for the long winded explaination, but I'll even consider design changes if this all makes sense to anyone that cares to comment.
Any input would be appreciated.
I'm using a subscription to the PropertyChanged events of the Entity in question. It seems like a lot of work to filter out all the events for a couple of fields.
Using RX, I'm hoping that the resources used are minimal, and the weak reference avoids the memory link issue when a strong reference is used to deal with events:
Observable.FromEventPattern<PropertyChangedEventArgs>(this.FlowEntity, "PropertyChanged")
.Where(pPropertyChanged => (
pPropertyChanged.EventArgs.PropertyName.EndsWith("Date")) ||
pPropertyChanged.EventArgs.PropertyName == "Capacity"
)
.Subscribe(pObserver => this.RaiseFlowEntityDateChanged(this, pObserver.EventArgs));
FlowEntity is the child entity that I'm monitoring from the parent. I then raise custom event using the parent entity, rather than the entity that actually holds the event.
I can't raise this event from the partial methods, as the child entity would not have the context of the parent.
In Core Data, most of the time relationships are modeled bidirectional. But the docs say in another place:
It typically only makes sense to model
a to-one relationship in one
direction.
Within Core Data you should always use a bi-directional relationship unless you have an extreme edge case. If you use one directional relationships then you are going to incur performance penalties within core data itself as well as have issues with referential integrity.
Unless you know specifically why you need a uni-directional relationship then you should always do a bi-directional relationship; the rule is that simple.
While Franci's answer is interesting, I have to disagree with it. Even in the examples he provided you should have a bi-directional relationship. There are almost no situations where a uni-directional relationship is going to be a better fit.
The answer is determined by the referential integrity requirements you want to enforce. If updating or removing the object on either side affects the object on the other side of the relationship, you need two-way. However, if updating/removing the object on one side does not affect the object on the other, then a one way is a better model.
Take for example a parent-children model with a 0..n : 1 cardinality (I prefer the 1 : 0..n representation, but for the sake of argument let's reverse it). Adding a new child, updating an existing child or deleting a child has no effect on the parent object, so there's no need for the parent to know explicitly about all the children (except when it comes time to pay college tuition). However, removing the parent has an adverse effect on the children objects, as they need to be deleted or re-parented, otherwise are orphaned and in an invalid state. Thus, it's better to model it as a one-way relationship. Another example is inventory - parts catalog relationship, again with 0..n : 1 cardinality.
It's a matter of ownership: usually it doesn't make sense to have a bidirectional relationship because an entity conceptually owns the other one.
Think about some examples. If you have a structure in which you have users and an user can have a simple bank account associated with him. If you make the relation bidirectional you mean that an user owns an account but also an account owns an user.
This will make sense because you don't want to delete an user whenever you delete his account. That's why usually you don't need to have it bidirectional: because it's an additional constraint that is not needed since most of the time you will have an entity that has the other but not vice-versa.
I think you read the whole document about relations you referenced in your question.
The document also describes all disadvantages of using unidirectional relations, and that only under very rare circumstances it makes sense to create unidirectional relations.
As a general rule i would strongly recommend creating bidirectional relations, except you are knowing exactly why not to do so.