I’m faced with a design decision that doesn’t smell to me, but gives me pause. Take a look at the following code sample:
public interface IGenerator { ///<summary> /// Combines two generators; performs magic as well /// </summary> BaseGenerator Combine(BaseGenerator next); ///<summary> /// Does what a generator does. /// </summary> object GenerateLolKThx(); } public abstract class BaseGenerator : IGenerator { ///<summary> /// Combines two generators; performs magic as well /// </summary> public BaseGenerator Combine(BaseGenerator next) { // do stuff that I really don't want implementors to try and do // because its complex and can result in bad juju if done wrong return SuperSecretCombine(this, next); } ///<summary> /// Does what a generator does. /// </summary> public abstract object GenerateLolKThx(); /* other base class methods */ }
I don’t want to go into more detail about WHY I don’t want to trust implementors with the Combine method; suffice it to say its complex. I do, however, want to do my best to force anybody who wants to implement IGenerator to extend BaseGenerator, as that’s the only way to properly combine two generators. This is enforced by the interface itself.
I’m worried that there are unexpected issues (indicated by a ‘smell’) caused by my referencing an implementation of an interface within that interface. But I also know that this sort of thing isn’t unheard of in CS, nor is it in and of itself bad (i.e., an XML schema that describes XSDs and language compilers that are written in the language they compile).
Here’s my answer: one of the purposes (perhaps even the main one) of separating interface from implementation is to make it possible to create many different implementations for an interface. Binding an interface to a particular implementing class breaks this.
You are effectively saying – ‘this interface must be implemented by a BaseGenerator or its subclass’, but then why separate
IGeneratorfromBaseGenerator?