I'm writing a library for use in scientific computing and ran into a bit of a quandary. The types at work here are a class
M which consists of some
data and a reference to a container class
C. There are many different implementations of
C and I devoted a lot of work to making sure that
M objects could use
C objects without knowing their internal representation.
The code may be used for high-performance scientific computing someday, so speed actually is a concern. If
M were to break the encapsulation of
C objects, the code could run faster. I tested this and indeed I could get a 50% speedup. But, that would involve lots of repeated code and violation of the open-closed principle.
Alternatively, I can take the behavior that
M needs to perform and delegate it to
C. By default,
C will use the same implementation-agnostic algorithm that I had before, but the logic has just moved downtown to a new class. The advantage of this approach is that, if
CO is an implementation of
C which can do substantially better than the default implementation, it can override that method with its own version.
There is, at present, only 1 method that
M will need to delegate to
C. I can imagine at most 2 more behaviors that will need to be dealt with in this way. There may be a bit of repeated code, but it could be handled with a code generator too.
Is this a common approach? If so, what's it called? If not, is that because it's a terrible idea for some reason that I haven't noticed? It's not quite the strategy pattern; most of the container objects don't even bother implementing their own strategy, they use the default.