Delegation vs multiple non-const Gets

S

spaceboy

Hi !

This is my problem :

I have a big class structure that is something like this :

A contains B contains a vector of C contains D contains a vector of E.

I have an object of A and I want to add an E object in D.

I thought of two options :

1. I call a series of non-const Get function like this (simplified) :

ObjA.GetObjB().GetObjC(indx1).GetObjD().AddEObject(objE);

I don't like this because de Get functions are non-const. These are
provoking side effects and does not encapsulate the modification.

2. Delegate the work down the hierarchy.

A::AddEObject(indx1,ObjE)
{
m_ObjB.AddEObject(ObjE);
}

B::AddEObject(indx1,ObjE)
{
m_ContainerC[indx1].AddEObject(ObjE);
}

C::AddEObject(ObjE)
{
m_ObjD.AddEObject(ObjE);
}

D::AddEObject(ObjE)
{
m_ContainerE.push_back(ObjE);
}

I don't like this either. It seems overkill to me and it will
complexify the maintenance because if D::AddEObject changes, it will
probably mean that all the other AddEObject functions have to change
also.

Do anybody have a 3rd option ?

Thanks !
 
O

ondra.holub

I think the first solution you mentioned is correct. When Get methods
return references, there is no problem. If you need to make it in some
cycle, you can store reference to last level and reuse it.

I do not know any better solution without change of data structure.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

spaceboy said:
2. Delegate the work down the hierarchy.

A::AddEObject(indx1,ObjE)
{
m_ObjB.AddEObject(ObjE);
}

B::AddEObject(indx1,ObjE)
{
m_ContainerC[indx1].AddEObject(ObjE);
}

C::AddEObject(ObjE)
{
m_ObjD.AddEObject(ObjE);
}

D::AddEObject(ObjE)
{
m_ContainerE.push_back(ObjE);
}

I don't like this either. It seems overkill to me and it will
complexify the maintenance because if D::AddEObject changes, it will
probably mean that all the other AddEObject functions have to change
also.

It looks like you are exposing internal details of any class in the
hierarchy to all the upper levels. This will make the hierarchy difficult
to maintain no matter what of the two ways you use.
 
Z

zwi

If I have understood he is not using inheritance he is using
composition.

zwi

Julián Albo ha scritto:
spaceboy said:
2. Delegate the work down the hierarchy.

A::AddEObject(indx1,ObjE)
{
m_ObjB.AddEObject(ObjE);
}

B::AddEObject(indx1,ObjE)
{
m_ContainerC[indx1].AddEObject(ObjE);
}

C::AddEObject(ObjE)
{
m_ObjD.AddEObject(ObjE);
}

D::AddEObject(ObjE)
{
m_ContainerE.push_back(ObjE);
}

I don't like this either. It seems overkill to me and it will
complexify the maintenance because if D::AddEObject changes, it will
probably mean that all the other AddEObject functions have to change
also.

It looks like you are exposing internal details of any class in the
hierarchy to all the upper levels. This will make the hierarchy difficult
to maintain no matter what of the two ways you use.
 
D

David Harmon

On 17 Nov 2006 08:14:41 -0800 in comp.lang.c++, "spaceboy"
I thought of two options :

1. I call a series of non-const Get function like this (simplified) :

ObjA.GetObjB().GetObjC(indx1).GetObjD().AddEObject(objE);

The rest of the application should not be made dependent on the internal
structure of your class in such a way! I don't know just how far the
hierarchy you should delegate, but at least at the app level provide a
method that does what needs to be done.
http://en.wikipedia.org/wiki/Law_of_Demeter
 
S

spaceboy

David said:
On 17 Nov 2006 08:14:41 -0800 in comp.lang.c++, "spaceboy"


The rest of the application should not be made dependent on the internal
structure of your class in such a way! I don't know just how far the
hierarchy you should delegate, but at least at the app level provide a
method that does what needs to be done.
http://en.wikipedia.org/wiki/Law_of_Demeter

Thanks for answering !

I knew that option #1 was not good but I did'nt know it had a name,
thanks for the information.

Like it's said on Wikipedia : "the disadvantage of the Law of Demeter
is that it requires writing a large number of small "wrapper" methods
to propagate method calls to the components - these can increase
initial development time, increase space overhead, and noticeably
decrease performance. Automated tools exist to at least partially
counteract these problems."

That means that they suggest that I use my option #2 but warns that it
has consequences...

I guess no perfect solution exists...

Thanks !
 
?

=?iso-8859-1?q?Kirit_S=E6lensminde?=

spaceboy said:
Hi !

This is my problem :

I have a big class structure that is something like this :

A contains B contains a vector of C contains D contains a vector of E.

I have an object of A and I want to add an E object in D.

I thought of two options :

1. I call a series of non-const Get function like this (simplified) :

ObjA.GetObjB().GetObjC(indx1).GetObjD().AddEObject(objE);

I don't like this because de Get functions are non-const. These are
provoking side effects and does not encapsulate the modification.

2. Delegate the work down the hierarchy.

A::AddEObject(indx1,ObjE)
{
m_ObjB.AddEObject(ObjE);
}

B::AddEObject(indx1,ObjE)
{
m_ContainerC[indx1].AddEObject(ObjE);
}

C::AddEObject(ObjE)
{
m_ObjD.AddEObject(ObjE);
}

D::AddEObject(ObjE)
{
m_ContainerE.push_back(ObjE);
}

I don't like this either. It seems overkill to me and it will
complexify the maintenance because if D::AddEObject changes, it will
probably mean that all the other AddEObject functions have to change
also.

Do anybody have a 3rd option ?

Generally I'd have to say that this is often a consequence of poor
design. Why is A adding an E to D? Maybe the problem is better
reformulated in such a way that this doesn't happen.

If you cannot think of a way around it then you're saying that the
coupling between these classes is high and there's no way to get it
working better.

What are the classes actually doing?


As an aside, I would never use 'get' or 'set' in accessor names in C++.
They strike me as non-idiomatic in a language that allows overloading
and it also exposes implementation details of your class.


K
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top