I'm regularly seeing the following pattern:
public abstract class BaseItem
{
BaseItem[] children;
// ...
public void DoSomethingWithStuff()
{
StuffCollection collection = new StuffCollection();
foreach(child c : children) c.AddRequiredStuff(collection);
// do something with the collection ...
}
public abstract void AddRequiredStuff(StuffCollection collection);
}
public class ConcreteItem : BaseItem
{
// ...
public override void AddRequiredStuff(StuffCollection collection)
{
Stuff stuff;
// ...
collection.Add(stuff);
}
}
Where I would use something like this, for better information hiding:
public abstract class BaseItem
{
BaseItem[] children;
// ...
public void DoSomethingWithStuff()
{
StuffCollection collection = new StuffCollection();
foreach(child c : children) collection.AddRange(c.RequiredStuff());
// do something with the collection ...
}
public abstract StuffCollection RequiredStuff();
}
public class ConcreteItem : BaseItem
{
// ...
public override StuffCollection RequiredStuff()
{
StuffCollection stuffCollection;
Stuff stuff;
// ...
stuffCollection.Add(stuff);
return stuffCollection;
}
}
What are pros and cons of each solution?
For me, giving the implementation access to parent's information is some how disconcerting. On the other hand, initializing a new list, just to collect the items is a useless overhead ...
What is the better design? How would it change, if DoSomethingWithStuff wouldn't be part of BaseItem but a third class?
PS: there might be missing semicolons, or typos; sorry for that! The above code is not meant to be executed, but just for illustration.