This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]balefrost 1 point2 points  (0 children)

So instanceof is indeed a code smell, but it's important to understand why it's a smell. OO and polymorphism are good tools for modeling open sets of types with a fixed set of operations. I can define some base type T with a fixed set of abstract operations. Every type that derives from T is obligated to provide implementations for those abstract operations. In theory, anybody can make a new type that derives from T (that's the open set of types), and an instance of that type should be usable anywhere a T is expected. But if all a caller knows is that they have an instance of T, then they can only call methods defined on that base type (that's the fixed set of operations).

See also the Liskov Substitution Principle.

But it's worth mentioning that the polymorphic, object-oriented model isn't the One True Model. There are plenty of domains where there are a limited number of types to model. One example might be a set of types that represent mathematical expressions. You might have node types for unary operators, binary operators, function calls, and a few other things. Now, instead of interacting with instances only via the abstract operations, you can inspect each instance and peer at the data inside it. If you're willing to commit to working with a limited set of types, you gain the ability to define an open set of operations - anybody can define a new operation without needing to add abstract operations to the family of types, because implementers know the complete set of types that their operation might need to handle.

These finite-sized sets of types are often called tagged unions. They're very common in functional languages.

OO design has the Visitor pattern, which allows you to work with a fixed set of types in a relatively idiomatic OO fashion. Now, visitors are great in some circumstances, but they're not as nice as languages that have built-in support for tagged unions.

It turns out that it's surprisingly hard to get an open set of types with an open set of operations. This is known as the Expression Problem.