What is wrong with using inheritance to replace an if?
If the test would have appeared in 20 places,
I see that you didn't even answer your own question!
Even if I had 20 ifs and they were all
the same test and they all represented a clean
bifurcation of a design, I'd still scream at you if your
first thought of how to remove the ifs was inheritance.
If you use only inheritance then you replace:
sub Widget::Munge {
# code block A
if( $self->is_blue() ) {
# code block B
} else {
# code block C
}
# code block D
}
with
sub Widget::Munge {
# code block A
# code block C
# code block D
}
sub Widget::Blue::Munge {
# code block A
# code block B
# code block D
}
plus other code to implement the object...
Now multiply that by 20. Gee, great solution. Now instead
of 20 repeated ifs we have 40 repeated blocks of code.
Oh, I'm sorry, you meant to also abstract out the code in
the if blocks as separate functions. Okay, so now we have
40 new functions. What are you going to name them all?
Does each of the 40 have a single, clear purpose that it
serves well?
Or are you assuming that each of the ifs also surround
identical code? Well, then your problem isn't that you
20 ifs; your problem is that you have 20 duplicated
chunks of code. So abstract that out as a function and
now we have 1 if and using the sledgehammer of inheritance
to squish it is still not the best first choice.
Even if we decide that we have a case where using two
functions in place of one if makes sense, then I'd first
consider just storing a reference to the function in the
object. If we have a bunch of cases like this and creating
another class is warranted, I'd still prefer to have the
original object contain a reference to these new objects
rather than resorting to inheritance.
From Advanced Perl Programming:
Perl supports only [implementation] inheritance. [....]
Subclassing is not easy, as Erich Gamma et al. say in Design Patterns:
Designing a subclass also requires an in-depth understanding of the parent class. For example, overriding
one operation might require overriding another. An overridden operation might be required to call an
inherited operation. And subclassing can lead to an explosion of classes, because you might have to
introduce many new subclasses for even a simple extension.
They suggest using composition instead, a topic we will touch on shortly.
and
When C++ came along, I quickly became enthusiastic about a
language that supported inheritance, and attempted to
implement the widget set in C++. Then when John
Ousterhout's Tk came along, I marveled at the ease of
creating widgets, even though it was in C and provided all
the features that Motif provides (and much more). The Tk
architecture used composition, not inheritance.
If Perl supported other types of inheritance, then I'd be
less critical of the use of inheritance in Perl.
But even Perl's version of implementation inheritance has
extra pitfalls beyond those in most languages. But I'll
save the details for a meditation since few will benefit
from an analysis deep in an old thread.
So, yes, using inheritance in Perl to remove an if
is still likely to tempt me to hunt you down and kill you. (:
-
tye
(but my friends call me "Tye") |