Why Implements is ‘Evil’

I stumbled across this really old article titled ‘Why Extends Is Evil’ by Allen Holub.
A solid bunch of OO practitioners out there seem to think along the lines of what this article is stating, namely, that using ‘extends’ is bad, and you should rather implement interfaces. The problem I have with this view is that I have come across a lot of software engineers out there who follow this view, but to a degree that they seem to be suffering from a kind of ‘implementitis-syndrome’.

Exhibit A :

The above diagram comes from a project I had the misfortune of working on for a company that will remain nameless. The architecture of the system shocked me so much when I first started on the project that I had to write down the UML diagram, to figure out what the hell was going on. Everything in this diagram is an interface save for about 3 classes that I have coloured blue. There obviously was some ridiculous interface bloat going on, also everything could probably be represented in only two or three interfaces or super classes.

My point is that, had this ball of mud contained an ‘extends chain’ going straight through the middle of this diagram, while still looking pretty awful, it would have started to make a bit more sense.

Extends adds semantic structure. Rather than looking like a tumbleweed, your class diagram would look more like a tree. The classes extending each other act like the tree trunk.

Extends also adds semantic meaning. An extends relationship is a IS A relationship, and implements relationship is a IS LIKE A relationship. Interfaces should end in “-able” (Runnable, Clonable), because they are defining a characterisitic about the object. You wouldn’t have a car implement a vehicle.. that is clearly an IS A relationship.

If you were to define everything as an interface. Everything just becomes vague mush.

Holub talks about a ‘fragile base class problem’. I think you can avoid this problem by making all classes that get extended from abstract. A developer is not going to be as inclined to play around with the internals of an abstract class; the developer knows that classes extend from it. I also think that liberal use of abstract methods prevents the base class from being fragile. In essence really, I think overriding non-abstract methods is the real problem in this story.

At the end of the day you should really try and avoid inheritence, and only use it when things can’t be done with composition. But my tip would be to leave implements out of the picture until you find a proper inheritence structure using extends.

Posted in Uncategorized | Tagged , , , , , | 5 Comments

5 Responses to Why Implements is ‘Evil’

  1. Tom B says:

    Thank you! Someone speaking sense! It pains me to see people saying “extends is evil” when they don’t understand it. It is abused too much, and used as a crutch but it does have a place.

  2. Jim says:

    The poor application of a principle is not an justifiable argument against the principle itself. Is it true that because there are horribly poorly written programs, programming itself should be rejected? Anyone could come up with an equally ugly chain of extension, but in that case it would be far worse. Now not only do you rely upon all of the declared behaviors of those classes, you may also rely upon the particular implementation of those behaviors. That is the Fragile Base Class problem.

    Declaring a class to be abstract does not improve this in any way. The only action that can have any affect on the problem is to make it impossible to rely on the implementation. Some gains can be made in this direction by declaring methods to be final.

    Additionally, implementing an interface is in fact an IS A relationship. Iterator is an interface. An ArrayList will return an object that implements the Iterator interface. The object returned by the ArrayList IS AN Iterator. If Vehicle is an interface and Car is an implementation, it is still true that Car IS A Vehicle. Vehicle would define what behaviors are common to all vehicles, and Car would provide an implementation specific to that kind of Vehicle.

    In Object-Oriented programming, the what is more important than the how. That is the nature of abstraction.

    • felixzacat says:

      The ‘fragile base class’ is a fact of life. If you change something at the base level, ie: I change the drawLegend() method on Chart, then it is going to have an effect on its sub-class XYChart, and also on its sub-sub-class LineChart and ScatterChart. However if I have drawLegend() method as an INTERFACE, then I am going to have to implement it for every class. I have just lost a lot of re-use capabilities.

      Also, if I have an abstract class called Vehicle then I can stuff it full of methods that are common across the subclasses: eg. drive(), openDoor(), moveSteeringWheel(). These are common and I don’t have to implement them again for the subclasses. This is re-use pure and simple. I can’t instantiate a vehicle but it contains a lot of code that its children use.

      I apologise for using saying interfaces are ‘IS LIKE A’. I’m wrong there. My take on it is that interfaces are a more ‘weak’ relationship if you will. I have no problems with interfaces, but they need to be used in conjunction with a conceptually robust core inheritance structure or you are not going to be able to see the forest for the trees.

  3. Piers Powlesland says:

    Im sorry but this article is complete rubbish, as the previous commenter pointed out “implementing an interface is in fact an IS A relationship” If you didn’t realise that you really shouldn’t be getting paid to write any code and you definitely should not be advising people on how not to use interfaces.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">