I have a CoreData entity X, and controllers for this entity, XController.
Now there's another entity, XGroup, containing a collection of X entities, and a XGroupController.
Now the problem is that XGroupController needs to interact with XController, and it would be nice to just pass XGroupController a XGroup to observe, and then get the XControllers from the X entities.
So the question is: is it a good idea to store a (weak, to avoid retain cycles) reference to a controller in an entity? It just feels a bit "wrong". Is there another design pattern for this?
[Edit] Some more information:
XController/XGroupController are view controllers; and the reason why it felt "wrong" is that the view layer shouldn't be in the model layer. So #TechZen is right with his first paragraph.
However, how would I do that if I don't have that reference?
The way I see is to pass XGroupController all existing XControllers (plus update them when they change), and then when the items in the XGroup change, find the corresponding controllers (by checking if the XControllers property for it's X entity is in the XGroup) and finally talk to the XControllers.
I have to do work again for stuff the model already handles very nicely.
Doesn't it make the model layer kind of pointless if I have to handle groups in the controller layer another time?
The difference that makes in terms of Loc/complexity is just so significant, am I missing something? (Perhaps I should add that in my scenario it doesn't make sense to store the information XGroupController needs to give to XController via the model).
If by "controller" you mean a MVC view/interface controller then yes it is wrong because it breaks encapsulation. The data model should be completely unconcerned with how it's data is displayed.
If your "controller" is just an entity with that name then you probably want to use a fetched relationship to get the two controllers to talk to each other. That prevents circular relationships in the object graph.
Related
[ Follow up from this question & comments: Should entity have methods and if so how to prevent them from being called outside aggregate ]
As the title says: i am not clear about what is the actual/precise purpose of entity as a child in aggregate?
According to what i've read on many places, these are the properties of entity that is a child of aggregate:
It has identity local to aggregate
It cannot be accessed directly but through aggregate root only
It should have methods
It should not be exposed from aggregate
In my mind, that translates to several problems:
Entity should be private to aggregate
We need a read only copy Value-Object to expose information from an entity (at least for a repository to be able to read it in order to save to db, for example)
Methods that we have on entity are duplicated on Aggregate (or, vice versa, methods we have to have on Aggregate that handle entity are duplicated on entity)
So, why do we have an entity at all instead of Value Objects only? It seams much more convenient to have only value objects, all methods on aggregate and expose value objects (which we already do copying entity infos).
PS.
I would like to focus to child entity on aggregate, not collections of entities.
[UPDATE in response to Constantin Galbenu answer & comments]
So, effectively, you would have something like this?
public class Aggregate {
...
private _someNestedEntity;
public SomeNestedEntityImmutableState EntityState {
get {
return this._someNestedEntity.getState();
}
}
public ChangeSomethingOnNestedEntity(params) {
this._someNestedEntity.someCommandMethod(params);
}
}
You are thinking about data. Stop that. :) Entities and value objects are not data. They are objects that you can use to model your problem domain. Entities and Value Objects are just a classification of things that naturally arise if you just model a problem.
Entity should be private to aggregate
Yes. Furthermore all state in an object should be private and inaccessible from the outside.
We need a read only copy Value-Object to expose information from an entity (at least for a repository to be able to read it in order to save to db, for example)
No. We don't expose information that is already available. If the information is already available, that means somebody is already responsible for it. So contact that object to do things for you, you don't need the data! This is essentially what the Law of Demeter tells us.
"Repositories" as often implemented do need access to the data, you're right. They are a bad pattern. They are often coupled with ORM, which is even worse in this context, because you lose all control over your data.
Methods that we have on entity are duplicated on Aggregate (or, vice versa, methods we have to have on Aggregate that handle entity are duplicated on entity)
The trick is, you don't have to. Every object (class) you create is there for a reason. As described previously to create an additional abstraction, model a part of the domain. If you do that, an "aggregate" object, that exist on a higher level of abstraction will never want to offer the same methods as objects below. That would mean that there is no abstraction whatsoever.
This use-case only arises when creating data-oriented objects that do little else than holding data. Obviously you would wonder how you could do anything with these if you can't get the data out. It is however a good indicator that your design is not yet complete.
Entity should be private to aggregate
Yes. And I do not think it is a problem. Continue reading to understand why.
We need a read only copy Value-Object to expose information from an entity (at least for a repository to be able to read it in order to
save to db, for example)
No. Make your aggregates return the data that needs to be persisted and/or need to be raised in a event on every method of the aggregate.
Raw example. Real world would need more finegrained response and maybe performMove function need to use the output of game.performMove to build propper structures for persistence and eventPublisher:
public void performMove(String gameId, String playerId, Move move) {
Game game = this.gameRepository.load(gameId); //Game is the AR
List<event> events = game.performMove(playerId, move); //Do something
persistence.apply(events) //events contains ID's of entities so the persistence is able to apply the event and save changes usign the ID's and changed data wich comes in the event too.
this.eventPublisher.publish(events); //notify that something happens to the rest of the system
}
Do the same with inner entities. Let the entity return the data that changed because its method call, including its ID, capture this data in the AR and build propper output for persistence and eventPublisher. This way you do not need even to expose public readonly property with entity ID to the AR and the AR neither about its internal data to the application service. This is the way to get rid of Getter/Setters bag objects.
Methods that we have on entity are duplicated on Aggregate (or, vice versa, methods we have to have on Aggregate that handle entity
are duplicated on entity)
Sometimes the business rules, to check and apply, belongs exclusively to one entity and its internal state and AR just act as gateway. It is Ok but if you find this patter too much then it is a sign about wrong AR design. Maybe the inner entity should be the AR instead a inner entity, maybe you need to split the AR into serveral AR's (inand one the them is the old ner entity), etc... Do not be affraid about having classes that just have one or two methods.
In response of dee zg comments:
What does persistance.apply(events) precisely do? does it save whole
aggregate or entities only?
Neither. Aggregates and entities are domain concepts, not persistence concepts; you can have document store, column store, relational, etc that does not need to match 1 to 1 your domain concepts. You do not read Aggregates and entities from persitence; you build aggregates and entities in memory with data readed from persistence. The aggregate itself does not need to be persisted, this is just a possible implementation detail. Remember that the aggregate is just a construct to organize business rules, it's not a meant to be a representation of state.
Your events have context (user intents) and the data that have been changed (along with the ID's needed to identify things in persistence) so it is incredible easy to write an apply function in the persistence layer that knows, i.e. what sql instruction in case of relational DB, what to execute in order to apply the event and persist the changes.
Could you please provide example when&why its better (or even
inevitable?) to use child entity instead of separate AR referenced by
its Id as value object?
Why do you design and model a class with state and behaviour?
To abstract, encapsulate, reuse, etc. Basic SOLID design. If the entity has everything needed to ensure domain rules and invariants for a operation then the entity is the AR for that operation. If you need extra domain rules checkings that can not be done by the entity (i.e. the entity does not have enough inner state to accomplish the check or does not naturaly fit into the entity and what represents) then you have to redesign; some times could be to model an aggregate that does the extra domain rules checkings and delegate the other domain rules checking to the inner entity, some times could be change the entity to include the new things. It is too domain context dependant so I can not say that there is a fixed redesign strategy.
Keep in mind that you do not model aggregates and entities in your code. You model just classes with behaviour to check domain rules and the state needed to do that checkings and response whith the changes. These classes can act as aggregates or entities for different operations. These terms are used just to help to comunicate and understand the role of the class on each operation context. Of course, you can be in the situation that the operation does not fit into a entity and you could model an aggregate with a V.O. persistence ID and it is OK (sadly, in DDD, without knowing domain context almost everything is OK by default).
Do you wanna some more enlightment from someone that explains things much better than me? (not being native english speaker is a handicap for theese complex issues) Take a look here:
https://blog.sapiensworks.com/post/2016/07/14/DDD-Aggregate-Decoded-1
http://blog.sapiensworks.com/post/2016/07/14/DDD-Aggregate-Decoded-2
http://blog.sapiensworks.com/post/2016/07/14/DDD-Aggregate-Decoded-3
It has identity local to aggregate
In a logical sense, probably, but concretely implementing this with the persistence means we have is often unnecessarily complex.
We need a read only copy Value-Object to expose information from an
entity (at least for a repository to be able to read it in order to
save to db, for example)
Not necessarily, you could have read-only entities for instance.
The repository part of the problem was already addressed in another question. Reads aren't an issue, and there are multiple techniques to prevent write access from the outside world but still allow the persistence layer to populate an entity directly or indirectly.
So, why do we have an entity at all instead of Value Objects only?
You might be somewhat hastily putting concerns in the same basket which really are slightly different
Encapsulation of operations
Aggregate level invariant enforcement
Read access
Write access
Entity or VO data integrity
Just because Value Objects are best made immutable and don't enforce aggregate-level invariants (they do enforce their own data integrity though) doesn't mean Entities can't have a fine-tuned combination of some of the same characteristics.
These questions that you have do not exist in a CQRS architecture, where the Write model (the Aggregate) is different from a Read model. In a flat architecture, the Aggregate must expose read/query methods, otherwise it would be pointless.
Entity should be private to aggregate
Yes, in this way you are clearly expressing the fact that they are not for external use.
We need a read only copy Value-Object to expose information from an entity (at least for a repository to be able to read it in order to save to db, for example)
The Repositories are a special case and should not be see in the same way as Application/Presentation code. They could be part of the same package/module, in other words they should be able to access the nested entities.
The entities can be viewed/implemented as object with an immutable ID and a Value object representing its state, something like this (in pseudocode):
class SomeNestedEntity
{
private readonly ID;
private SomeNestedEntityImmutableState state;
public getState(){ return state; }
public someCommandMethod(){ state = state.mutateSomehow(); }
}
So you see? You could safely return the state of the nested entity, as it is immutable. There would be some problem with the Law of Demeter but this is a decision that you would have to make; if you break it by returning the state you make the code simpler to write for the first time but the coupling increases.
Methods that we have on entity are duplicated on Aggregate (or, vice versa, methods we have to have on Aggregate that handle entity are duplicated on entity)
Yes, this protect the Aggregate's encapsulation and also permits the Aggregate to protect it's invariants.
I won't write too much. Just an example. A car and a gear. The car is the aggregate root. The gear is a child entity
I am using Jimmy Bogard's lovely Automapper to map my API model to the POCO classes (domain model).
The API model does not contain certain attributes of the domain model which are necessary for the domain model to be in valid state. In this scenario, when Automapper finishes its job, I have a fully constructed domain model in an invalid state.
Not using Automapper is not an option because there are too many attributes to hand code.
So, here is my question:
How do I use automapper to create the object in this manner while leaving the domain model in a valid state.
Thanks
This is probably too long for a comment:
Although Jimmy's answer is correct it may imply that your design may not be as encapsulated as it could be since you are going to have to expose a lot of state. This may be why there are comments around "anemic" models and "not fit for purpose".
If you are focused on behaviour then you may have something, totally hypothetical, as follows to make your customer a Gold customer:
customer.MakeGold();
However, using state you would now have to expose attributes that allow you to map to a Gold status. Internally your customer may have checked certain other state to determine the validity of the Gold status whereas that validity check has now moved out of the domain in the way Jimmy says he makes sure that the state is correct before passing it to the domain.
This is not so much an auto-mapper issue as it is a design issue. It also seems to indicate that your API/Integration model may be more data-centric.
On the other hand, if you are mapping to, say, command-style value objects that are handed to the domain it may not be as bad as that :)
// map my APIActivationDetails to Activate --- however automapper does this :)
var activate = AutoMapper.Map<Activate>().From(apiActivationDetails);
customer.Activate(activate);
Come to think of it... this seems to be what Jimmy is saying :P
"to map my API model to the POCO classes (domain model)"
Why would you ever want to map command object (your API model) attributes to domain objects? If that's what you are aiming for you will mostly end up with over-engineered CRUD, but certainly not a DDD solution.
Behaviors should be explicitly declared on aggregates and aggregates are responsible for mutating their own internal state according to the business invariants they protect.
That way, domain model clients can clearly state their intention and this intention isin't lost through the business process.
You shouldn't try to shove data into aggregates, instead you should ask them to perform a task.
I validate the API model before it gets mapped into my domain model, whether I'm using AutoMapper or not. The API model represents a command or action, so I'm validating the command before I apply it to my entity, not mutate my entity and then try to validate it afterwards. This also means all my validation attributes are on my API model.
I am designing my game with Entity/Component concepts of GameplayKit in iOS 9, for ShootComponent, should define bullet/missile as Entity?
Reason for Yes:
separate logic from its parent, e.g. playerTank or enemyTank;
if not, TankEntity need distinguish whether its bullet collide with other Entities or itself.
Reason for No:
it is not actual entity in logic world, which is fired by my tank or enemy turret;
bullet always be shot and disappeared, so game need add/remove it now and then;
For your comments pls.
Finally decided to define bullet/missile as entity, so it acts as entity in contact test, rendering and other components.
I would have add it as a component for the entity using it.
So you will be able to make any entity fire bullet or missile.
Keep in mind that your entity should only act as a simple reference with no logic in it.
First lets read Adam Martins original description of his terms. It appears Apple got the idea of entities and components from Martin:
Entity: The entity is a general-purpose object. Usually, it only consists of a unique id.
Component: the raw data for one aspect of the object, and how it interacts with the world.
System: "Each System runs continuously (as though each System had its own private thread) and performs global actions on every Entity that possesses a Component or Components that match that Systems query."
Martin is just defining terms for doing compositional design, which is an alternative to inheritance that is more recombinable and flexible.
So entities are what you might recognize as instances of a class, but classes have been stripped of all their data and methods, which has been moved out into components - and the entities just delegate to the components.
So your missile... it would be an instance of a class in normal OO terms - an object, right? And a missile can behave in a variety of ways... it can seek out an enemy, it can fly straight ahead, it can speed up, etc. It also has properties that indicate if it's hit an enemy, properties for its total damage, health, and so on.
So the missile is an entity while these various methods / data would be components of the missile entity.
Martins approach is interesting, and there hasn't been as much focus on compositional design as there has been OO (for what reason I don't really know), so I can see why Apple would adopt it for a game framework like this.
But his ideas don't seem very well fleshed out. For example, usually in compositional design there is a delegation hierarchy, where objects will keep delegating up a chain until some data or method is found. At the top there's one meta-object that everything delegates to. In this way objects are both components and entities - they act as both the delegating and the delegated to. But Martins terms don't support this... his model is flat - there are only entities, and then components that can be added to them, but no delegation between entities and no meta-object.
Maybe he felt this flat design was appropriate for game development. I have my doubts... you seem to want some kind of hierarchical structure of objects. I would look for a way to mix in inheritance, or setup some kind of custom delegation hierarchy where objects could act as both entities and components. You might look to see if this is possible within that framework, or if it isn't just write your own.
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 :)
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.