Suppose I'm writing some C++ code to visualize "Foo" objects. I have two ways of getting a "Foo": computing it from data, or from taking the pieces of a precomputed "Foo" and building a new "Foo".
Now, once a "Foo" is computed it's guaranteed to be good for visualization, but changing it may break this assumption. Therefore, I've decided to represent "Foos" in my code by a Foo class that has no mutating methods: once it is constructed and initialized, it doesn't change.
But there's a second way to make a "Foo": build it from a precomputed "Foo"'s components. I've come up with several methods of building a Foo from precomputed data:
Method 1: Constructor/Static methods
Perhaps the most obvious method would be to add a new constructor or a static method to Foo, call itfromPrecomputed, that would read the components of the precomputed Foo and make a new Foo object, checking that it is valid. To explain why I'd like to shy away from this, I have to complicate my example: Let's say that one component of a "Foo" is a collection of "Bars". Now, in terms of implementation, sometimes a "Bar" is represented as a std::vector<std::vector<Bar> >, sometimes as a Bar array[][2], sometimes as a std::vector<std::pair<Bar,Bar> >, and so on... I could have the user reorganize their data into a standardized form and have a single constructor for this standard, but this might require the user to perform an extra copy. I don't want to provide a static method for each format: readPrecomputedFormatA, readPrecomputedFormatB, and so on: this clutters the API.
Method 2: Make Foo mutable
If I exposed the addBar(Bar) method of Foo, then I could allow the user to iterate over their collection of "Bars" in their own way. This, however, makes Foo mutable. So I could compute a Foo that makes sense for visualization, then use addBar to add a Bar that makes the Foo no longer a "Foo". Not good.
Method 3: Make a friend "builder" class
I make a class called FooBuilder which has the addBar(Bar) method exposed. I make FooBuilder a friend of Foo and add a constructor to Foo that takes a FooBuilder. On calling this constructor, it checks to make sure that FooBuilder contains a valid "Foo" object, then swaps its empty representation of a Foo with what is inside the FooBuilder. Everybody is happy.
The only "messiness" about method #3 is that it requires a friendship, but it's worth it to maintain encapsulation I think. But this has got me thinking: is this an established pattern? Or is there another, better way of doing this that I don't know about?
Foobe aware of howBaris represented?Foois a special type of graph. I want to allow the user to build a precomputed graph, which means specifying the edges it contains. Internally,Foohas a representation of an edge object and a container for storing edges, but the user just has to specify a 2d array of integers. But there are many different ways that the user can represent a 2d array, and I don't want to force the user to make a copy of his/her data to conform to my special standard. It isn't as simple as having an addEdge(int,int) method, since the tree shouldn't be mutable.