Every so often, I run into a case where I want a collection of classes all to possess similar logic. For example, maybe I want both a Bird
and an Airplane
to be able to Fly()
. If you're thinking "strategy pattern", I would agree, but even with strategy, it's sometimes impossible to avoid duplicating code.
For example, let's say the following apply (and this is very similar to a real situation I recently encountered):
- Both
Bird
andAirplane
need to hold an instance of an object that implementsIFlyBehavior
. - Both
Bird
andAirplane
need to ask theIFlyBehavior
instance toFly()
whenOnReadyToFly()
is called. - Both
Bird
andAirplane
need to ask theIFlyBehavior
instance toLand()
whenOnReadyToLand()
is called. OnReadyToFly()
andOnReadyToLand()
are private.Bird
inheritsAnimal
andAirplane
inheritsPeopleMover
.
Now, let's say we later add Moth
, HotAirBalloon
, and 16 other objects, and let's say they all follow the same pattern.
We're now going to need 20 copies of the following code:
private IFlyBehavior _flyBehavior;
private void OnReadyToFly()
{
_flyBehavior.Fly();
}
private void OnReadyToLand()
{
_flyBehavior.Land();
}
Two things I don't like about this:
It's not very DRY (the same nine lines of code are repeated over and over again). If we discovered a bug or added a
BankRight()
toIFlyBehavior
, we would need to propogate the changes to all 20 classes.There's not any way to enforce that all 20 classes implement this repetitive internal logic consistently. We can't use an interface because interfaces only permit public members. We can't use an abstract base class because the objects already inherit base classes, and C# doesn't allow multiple inheritance (and even if the classes didn't already inherit classes, we might later wish to add a new behavior that implements, say,
ICrashable
, so an abstract base class is not always going to be a viable solution).
What if...?
What if C# had a new construct, say pattern
or template
or [fill in your idea here], that worked like an interface, but allowed you to put private or protected access modifiers on the members? You would still need to provide an implementation for each class, but if your class implemented the PFlyable
pattern, you would at least have a way to enforce that every class had the necessary boilerplate code to call Fly()
and Land()
. And, with a modern IDE like Visual Studio, you'd be able to automatically generate the code using the "Implement Pattern" command.
Personally, I think it would make more sense to just expand the meaning of interface to cover any contract, whether internal (private/protected) or external (public), but I suggested adding a whole new construct first because people seem to be very adamant about the meaning of the word "interface", and I didn't want semantics to become the focus of people's answers.
Questions:
Regardless of what you call it, I'd like to know whether the feature I'm suggesting here makes sense. Do we need some way to handle cases where we can't abstract away as much code as we'd like, due to the need for restrictive access modifiers or for reasons outside of the programmer's control?
Update
From AakashM's comment, I believe there is already a name for the feature I'm requesting: a Mixin. So, I guess my question can be shortened to: "Should C# allow Mixins?"