If I have two entities, Parent and Child, Parent needs to know about all of its Child children, and every Child instance needs to know about its parent Parent instance, how do I do this properly (in terms of DDD etc)?
The easy way would be to do parent.addChild(new Child(parent)), but this seems ugly - as well as:
parent.addChild(new Child()); // Then call some setParent method on child, which needs to be public
Do I need to use a factory here? And if so, how?
Thanks
One option would be to have a relevant instance method on the Parent class. A static Factory is probably not necessary here since you are operating on existing objects and simply need to connect object with another.
public class Parent {
// ...
public Child createChild() {
Child c = new Child(this);
this.addChild(c);
return c;
}
protected void addChild(c) {
// ...
}
// ...
}
public class Child {
public Child(Parent p) {
// ...
this.addParent(p);
}
protected addParent(Parent p) {
// ...
}
}
If the Child constructor needs arguments, you can pass those to the createChild method.
You are not limited to a single one approach. You should use the approach that fits you.
In SWT the child is linked to parent in constructor:
new Label(parentComposite, SWT.NONE);
After that parentComposite knows its child.
Note: SWT requires parent on creation which limits some functionality - you can't create child without specifying a child. This is limitation of the SWT.
In Swing you can create child widget and then add it to the parent.
Those above just the examples. Your personal solution will be based on your needs.
I would consider to use less methods, more consistency (don't leave your childs unlinked from parent)
Talking about code I would use following method:
Parent {
addChild(Child child) {
children.add(child);
child.setParent(this);
}
}
Hope that helps. Happy designing!
How about to do something like this:
public class Child {
Child (Parent parent) {
...
this.parent = parent;
parent.addChild(this);
}
}
So you can set parent to Child only while creating child.
Related
I have the following problem:
I have an aggregate root with multiple layers of one to many relationship.
Root -> has many
Child -> has many
GrandChild
I have Controller\s that handle logic done on each layer of the aggregate root.
I do not know how to handle the data access layer.
Should i just create a repository for the aggregate root and all Child and GrandChild operations get handled through it or it would be fine to create a repository for every level ?
Furthermore the GrandChildren entities in my case occupy a lot of space (they contain text) , thus i will be using a document database - RavenDB.
public class Root
{
public int ID{get;set;}
public IEnumerable<Child>Children;
}
public class Child
{
public int ChildID{get;set;}
public IEnumerable<Child>GrandChildren; //occupy a loot of space !
}
public class GrandChild
{
public int GrandChildID{get;set;}
}
public interface IGenericRepository<T>
{
bool Add<T>(T newValue);
T Get<T>(int id);
IEnumerable<T> GetAll();
bool Delete(int id);
bool Update<T>(T value);
}
Controller
public class ParentController
{
IGenericRepository<Root> repo;
public IActionResult<Root> Get(int rootId)
{
return this.repo.Get(rootId);
}
}
public class ChildControiller_V1
{
IGenericRepository<Child>repo;
public IActionResult<Child> Get(int childid)
{
this.repo.Get(childid); //the id is unique
}
}
Access through root
public class RootRepository:IGenericRepository<Root>
{
/// implementations
public IGenericRepository<Child> GetChildRepository()
{
return //some implementation of IGenericRepository for Child
}
}
public class ChildController_V2
{
IGenericRepository<Root>repo;
public IActionResult<Child> Get(int rootId,int childid)
{
var root=this.repo.Get(rootId);
var childRepo=root.GetChildRepository();
var get= childRepo.Get(childId);
}
}
I hope you get the idea.For more layers i would do this all the way down.What would be a good approach considering the lowest entities occupy a lot of space compared to the others?
Update
The Root will have to support Create,Delete - not much happening here
The Child will have to support Create,Delete - (The focus will be on GET
, something like GET 5 children starting from index=10 here)
The Grandchildren will have to support full CRUD with a heavy intensive work on Update .Their table size of GrandChildren will be >>>>> all the others combined.Every Grandchild will have a plain text column.
When i say table or column i am referring to their equivalent in a typical SQ L database
From a (classic)DDD point of view, repositories return fully materialized aggregates, where aggregates represent consistency/transactional boundaries. Having children and grandchildren repositories means you give that up and with it a big benefit of DDD. That being said, you need to determine where your consistency boundaries are. Are there constraints between the entities? If not, they can be there own aggregates. Remember that aggregates don't appear in other aggregates and references from an entity should only go to an aggregate root, not some other entity in another aggregates' hierarchy.
I already mentioned a few other points that may be interesting in my answer here, specifically a direction if the data is too much.
https://stackoverflow.com/a/59189413/2613363
Lastly, I will say Raven has versions (etags). Use them if you end up updating many child items.
I have a parent bean having one instance variable like below :
public Class ParentBean {
protected boolean show; // this variable will be used to show some UI component
public void action() {
// update show variable here
}
public boolean isShow() {
return show;
}
}
Is it a good design if I want to reuse the "show" variable in a child bean (to show other UI component specific to child bean ) as shown below :
public Class ChildBean extends ParentBean {
// override the action method from parent bean
public void action() {
// update show variable here
show = true /false;
}
}
In effect , show variable is being updated by "childBean" by overriding action() method.
Is this a good design practice ? Otherwise same thing has to be repeated in ChildBean to get this work done.
If you use the show variable for the same purpose in the subclass, as you seem to be doing in this example, then obviously you should reuse it, because otherwise you just end up writing the same code twice, which is contrary to the point of OOP.
In general, in OOP, it is common to override superclass methods in subclasses, as well as modifying superclass instance variables, as long as you know what the variable you are modifying is being used for (you don't want to be randomly changing instance variables in classes that you don't completely understand, or don't have access to the source of, because you don't want any unfortunate side effects), so when it's your own code, this is absolutely fine.
As a general guideline, if your options are either to copy and paste a massive hunk of code and use it unchanged, or subclass and use the superclass' instance variables or functions, it's better to subclass. Otherwise, you're missing out on the point of OOP.
Changing the value in subclass will not affect superclass variable
This is fine with respect to the design. When a subclass object is instantiated, it will have a different copy of variable. and If superclass object is instantiated it will have different copy.
It is. Having a protected variable means you are allowed to modify it into parent or children classes (remember every single instance of each class has its own property values). So, if you have some generic functionality which is valuable for all the children:
Parent class:
public void action(){
//update show variable here
show = true;
}
Appart from that, if you want to add some extra functionality in a specifical child:
Child class:
#Override
public void action(){
super.action();
//Extra functionality goes here
//You can also access parent's 'protected' fields
if (show){
System.out.println("Shown");
}
}
An example of the use:
Parent p = new Parent();
p.action();//Prints nothing
Child c = new Child();
p.action();//Prints 'shown'
Other than possibly constructors, and copying/cloning. Is there a need to reference an object with the same type as itself?
e.g.
class TEST {
TEST x;
void dosomething() {
TEST tmp;
...
}
TEST another_possible() {
...
}
}
Thank you.
Yes. For example:
A linked list node references the next node (and maybe previous node).
A tree node may reference other tree nodes -- as children or as parent.
A graph node may reference adjacent graph nodes.
An instance may wrap another instance (e.g., java.lang.Throwable and its cause).
Yes; it's called a recursive data type. Example, for a tree-like data structure:
public class Node
{
public string Name;
public List<Node> Children;
}
In a reflexive association relationship, for example.
Source: http://www.ibm.com/developerworks/rational/library/content/RationalEdge/sep04/bell/
I am a bit surprised that the (anti) pattern Singleton hadn't been posted yet. http://en.wikipedia.org/wiki/Singleton_pattern
I was coding a very simple case with 2 classes: Parent and Child. Parent has n children, and children has 1 Parent. I set up a bidirectional relationship between them.
I was trying to add a business rule to my parent, that rule checked for equality between the child's parent and the instance handling the call. It returned false when it should have returned true. So I simplified everything to get to the root of the problem. So I tested the same equality outside the POCO and it returned true:
Parent parent0 = session.Load<Parent>(0);
Child child = session.Load<Child>(0);
bool externalTest = parent0 == child.Parent;
I then coded a method for my Parent to test the exact same thing:
bool internalTest = parent0.IsRelated(child);
... Parent Class code
public virtual bool IsRelated(Child child)
{
return child.Parent == this;
}
...
And it returns false... I just don't get it. It's the exact same code.
More info:
So to get more info, I modified my test:
Parent parent0 = session.Load<Parent>(0);
Child child = session.Load<Child>(0);
bool externalTest = parent0 == child.Parent;
System.Diagnostics.Debug.WriteLine("outside parent: " + externalTest);
System.Diagnostics.Debug.WriteLine("Number of parent instances before call to IsRelated:" + Parent.NumberOfInstances);
parent0.IsRelated(child, parent0);
System.Diagnostics.Debug.WriteLine("Number of parent instances after call to IsRelated:" + Parent.NumberOfInstances);
... Parent Class code
public virtual void IsRelated(Child child, Parent sameAsThis)
{
bool internalTest = child.Parent == this;
System.Diagnostics.Debug.WriteLine("inside parent:" + internalTest);
bool sameTest = sameAsThis == this;
System.Diagnostics.Debug.WriteLine("this should equal sameAsThis:" + sameTest);
}
...
I passed the parent instance directly to itself and verify it was the same instance. Well it's not, I get another instance created when I enter the IsRelatedMethod.
Here are my test results:
outside parent: True
Number of parent instances before call to IsRelated:1
inside parent:False
this should equal sameAsThis:False
Number of parent instances after call to IsRelated:2
What am I doing wrong ?
For detailed mapping files and pocos, see (http://stackoverflow.com/questions/13253459/relationships-fixup-in-entityframework-vs-nhibernate)
This is because of the proxy that Nhibernate uses to lazy load entities. In your case the child's parent is a proxy instance.
To solve you problem simply change .Load to .Get
.load does not actually hit the database and populate the entity. See this blog post by Ayende for more info
I'm working on a project with NHibernate that classes similar to the following:
public class Parent {
public IList Children {get;set;}
// ...
}
public class Child {
// ...
}
I've got the Children property set to cascade all / delete orphan. Since I'm using the aggregate pattern and instances of Child class will only ever be referenced in the context of a Parent, I don't have a ChildRepository to delete the children directly - only a ParentRepository. However, when I retrieve the Parent object and call Parent.Children.Clear(), the children from the database are never deleted. How can I achieve this?
Deleting child entities is this easy - just remove them from the collection and then save the parent entity. The collection should be mapped with all-delete-orphans.
parent.Children.Clear();
session.Save( parent );
// or
parent.Children.RemoveAt(0);
session.Save( parent );
You can do this without Save() calls as well, unless your FlushMode is Never.
session.BeginTransaction();
parent.Children.Clear();
session.Transaction.Commit();
Using #Chris's UnitOfWork abstractionm this could look like:
using (var uow = new UnitOfWork()) {
parent.Children.Clear();
}