A different question of mine had to do with encapsulating member data structures inside classes. In order to understand this question better please read that question and look at the approach discussed.
One of the guys who answered that question said that the approach is good, but if I understood him correctly - he said that there should be a class existing just for the purpose of wrapping the collection, instead of an ordinary class offering a number of public methods just to access the member collection.
For example, instead of this:
class SomeClass{
// downright exposing the concrete collection.
Things[] someCollection;
// other stuff omitted
Thing[] getCollection(){return someCollection;}
}
Or this:
class SomeClass{
// encapsulating the collection, but inflating the class' public interface.
Thing[] someCollection;
// class functionality omitted.
public Thing getThing(int index){
return someCollection[index];
}
public int getSize(){
return someCollection.length;
}
public void setThing(int index, Thing thing){
someCollection[index] = thing;
}
public void removeThing(int index){
someCollection[index] = null;
}
}
We'll have this:
// encapsulating the collection - in a different class, dedicated to this.
class SomeClass{
CollectionWrapper someCollection;
CollectionWrapper getCollection(){return someCollection;}
}
class CollectionWrapper{
Thing[] someCollection;
public Thing getThing(int index){
return someCollection[index];
}
public int getSize(){
return someCollection.length;
}
public void setThing(int index, Thing thing){
someCollection[index] = thing;
}
public void removeThing(int index){
someCollection[index] = null;
}
}
This way, the inner data structure in SomeClass can change without affecting client code, and without forcing SomeClass to offer a lot of public methods just to access the inner collection. CollectionWrapper does this instead.
E.g. if the collection changes from an array to a List, the internal implementation of CollectionWrapper changes, but client code stays the same.
Also, the CollectionWrapper can hide certain things from the client code - from example, it can disallow mutation to the collection by not having the methods setThing and removeThing.
This approach to decoupling client code from the concrete data structure seems IMHO pretty good.
Is this approach common? What are it's downfalls? Is this used in practice?