I have been working with this code for quite a long time now, and I continually refactor and refactor and just keep running into different forms of the same problem. In the last couple of weeks I've tried to take a step back and really think about the design, motivated by the fact that the code was nearly impossible to write tests for (I read a book on TDD :) ). Below is the design I've converged on.
The program's job is to solve an image processing problem - the high level outline (hopefully from bottom to top) of the part of the design I'm interested in is:
- A Patch objects that define a square region in an image
- A PatchPair class that holds two patches to be compared
- A PixelDifference class that has a float Difference(PixelType, PixelType) function.
- A template PatchDifference<typename TPixelDifference> class that sums the difference corresponding pixels in a PatchPair using the provided PixelDifference class.
- A PairDifferences class that stores a collection of different difference types. Each PairPair has a PairDifferences object.
- A template SelfPatchCompare<typename TPatchDifference> that compares a specified patch to all other patches in an image
- A PatchBasedInpainting class. This is the object that would be instantiated from main(). The logic of this class is not the concern of the part of the design I'm worried about. The one part that it does involve is that at some point it needs to use a SelfPatchCompare<typename TPatchDifference> to compute the differences between a specific patch and all others.
The main problem is that at run time I'd like to specify which types of differences are computed. This is done at the very highest level of the program, and somehow has to get into the SelfPatchCompare class. Since SelfPatchCompare is templated on the type of difference to compute, I could either:
1) Subclass from a non-templated SelfPatchCompareSuperclass so I can store objects of type SelfPatchCompare<T>* in a vector<SelfPatchCompareSuperclass*> and instantiate each with a different TPatchDifference. This would work, but then each SelfPatchCompare object would have it's PatchPairs each containing only one difference. I'd then have to combine all of these PatchPair objects.
or
2) Provide a list of functions (via boost::function or similar) to the SelfPatchCompare object and loop over these functions in the main Compute function. This is what I did for a while, but the symantics are annoyingly complicated.
Would you prefer one of these over the other? Are there any other choices?
If you're interested, the code is here: https://github.com/daviddoria/PatchBasedInpainting
I can certainly clarify anything I explained poorly, or provide more details where needed. I know this is a pretty big problem, but it's tough coding something this big with an army of one and no collaboration :)
Thanks for any input!
David