Don’t names classes AbstractThing or ISerializable

Naming a class AbstractThing violates the Liskov Substitution Principle, and causes client code to read wrong. Call a class a name which you’d be happy to call any of the objects belong to the class.

If you want to borrow your friend’s phone, and you’re not sure what brand it is, how many times have you asked “Excuse me mate, can I borrow your abstract phone? Cheers.”

Object-oriented modeling and programming allows certain classes of objects to specialize other general classes of objects. For example, both a Rectangle and Circle are special types of of Shape.

Every Rectangle is a Shape. Everywhere you can use a Shape, you can use a Rectangle. Code that deals with a Rectangle (but which can also deal with Circles) might look like:

Shape s = .....;
s.drawTo(myGraphicsContext);

Using an object (e.g. a Rectangle) anywhere you can use a generalization of it (e.g. a Shape) is an important part of the object-oriented concept, and known as the Liskov Substitution Principle.

It’s also obvious: what sort of sentence or logic would make statements about shapes, but then not be applicable to rectangles?

If you name the generalization an AbstractShape, this principle is violated. A Rectangle isn’t an AbstractShape. If anything it’s a “Concrete Shape”! A rectangle isn’t abstract (in the sense of “I don’t know what type of shape this is. Could be a rectangle, could be anything else.”). Code using AbstractShape then reads wrong:

AbstractShape s = new Rectangle(...);

The same is true of interfaces. What do all objects which are serializable have in common? They are Serializable. Naming the interface ISerializable would lead to code like:

ISerializable s = new String("hello")

But s refers to a particular instance; a particular thing. There’s nothing abstract or “just an interface” about s. s is a String, which is a specialization of the more general type of thing called a Serializable. The line of code, including s’s type, must reflect what s actually is. It’s a serializable.

Further, what if you change an interface to an abstract class, or a concrete class to an abstract class, or vice-versa? The client code must be updated. While isn’t too much of a pain with refactoring tools, it still leads to the suspicion that irrelevant information about the tools used to construct the implementation are leaking out to client code.

A class of a set of objects is named to capture the common aspects of those objects. If all objects are rectangles, call their class Rectangle. Naming a superclass, abstract or not, is no different. What do all the object modeled have in common? Some are rectangles, some are circles, but they are all Shapes.

The objects being classified into classes are not AbstractShapes, BaseShapes, IShapes, or similar.

3 Responses to “Don’t names classes AbstractThing or ISerializable”

  1. Christian Says:

    Well…. yes. On the one hand.

    On the other hand, I find that naming abstract classes properly can be quite a challenge. After all, the coder should know that this is an abstract class, or an interface, when looking at the name.

    But what do you call an abstract controller in an MVC framework? “abstract class Controller {}” is no good – if you don’t have the source before you, you have no idea whether it can be instantiated or not. With many a internal object (i.e., one that doesn’t model a part of the problem domain, but is part of a generalized framework), there is no good name for the abstraction. I find myself ending up with clumsy names such as “BasicController” or “StandardController” (for classes that CAN be instantiated. It’s a crutch, and I know it, but I haven’t found a better solution yet.

    And with interfaces, all is good and well as long as the name adheres to the interface Suffixable – i.e., as long as you can easily add an “-able”, and all is well. However, this is not always the case. “public interface BusinessObjectable”?? As clumsy as IBusinessObject is, it still seems like the better solution to me.

  2. adrian Says:

    “After all, the coder should know that this is an abstract class, or an interface, when looking at the name”, I’m not sure I agree with that. Why would a coder need to know that? That would also necessarily mean you couldn’t change an abstract class to/from an interface to/from a concrete class, without changing all client code. I think this information, about the implementation of the thing you’re using (interface? class?) is “leaking” if it appears in client code.

    “abstract class Controller {} is no good – if you don’t have the source before you, you have no idea whether it can be instantiated or not”. I think you need to have documentation or an IDE which can tell you how to instantiate things. At the very least you need to know what constructors are available, what parameters they take, what types those parameters have, etc. One is not just going to blindly do “new Controller()” and hope it works. Given one needs this information, one would see that an abstract class (or interface) has no way of instantiating an object.

    “As clumsy as IBusinessObject is, it still seems like the better solution to me”, Obviously the -able is a nice prefix but, as you say, doesn’t always lend itself well to the situation at hand. I don’t have a problem with knowing that variable “x” is a BusinessObject. (Even if that’s an interface.)

  3. Christian Says:

    Yes, if you’re coding in a language that actually supports real object-orientation, and if you use an IDE worthy of the name, you’re absolutely right. The sad part is that not all of us are so privileged. I’m the bad cynical realist in this, I’m afraid.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

For inserting HTML or XML please remember to use &lt; instead of <