views:

31

answers:

1

Some of my classes should be treated differently. Which solution is better:

  1. Introduce new interface to my class hierarchy and check whether the class implements it or not, using RTTI (runtime time identification)
  2. Add a method which returns boolean value that indicates whether this class should be treated normally or deserves special treatment

The following examples illustrates the above situations:

1.

interface SpecialTreatment {}

class Base {}    

class Special extends Base implements SpecialTreatment {}

class Normal extends Base {}


Base reference = new Special();
if(reference instanceof SpecialTreatment)
    // do something special
else
    // normal class

2.

interface Treatment {
    boolean special();
}

class Base {}

class Special extends Base implements Treatment {
    boolean special() { return true; }
}

class Normal extends Base implements Treatment {
    boolean special() { return false; }
}

Treatment reference = new Special();
if(reference.special() == true)
    // do something special
else
    // normal class
+1  A: 

If the 'reason' for treating the class differently is a design decision then mark it as so via an interface signature as in solution 1.

If there is a chance that some state in your application would govern this, then use solution 2.

And example of this, is the java.io.Serializable interface with no methods or fields that is used to identify implementations that are serializable. You decide at design time whether the object was serializable.

A note on the performance of instanceof, after additional comment.

You could also look at using Annotations as an alternative...

-- EDIT AFTER TAKING COMMENTS ON BOARD ---

If you really want to not go down the instanceof (which is very fast) or annotations you could do this..

interface Special {
    bool isSpecial();
}

abstract class RuntimeSpecial implements Special {
    protected abstract bool _determineSpecial();

    public isSpecial() { return _determineSpecial(); }

}

class IsSpecial implements Special {
    public isSpecial() { return true; }
}

class IsNotSpecial implements Special {
    public isSpecial() { return false; }
}

Now extend whatever is appropriate....

Adrian Regan
does RTTI cost much more than simple late-binding via interfaces?
MarcAndreson
Adrian Regan
I heard that a programmer can use RTTI only when other solutions fail, and polymorphism can solve any problem more elegant. Are there any other patterns that can let me avoid RTTI ?
MarcAndreson
A programmer should examine **all** the available facilities of the given language/platform. The question you need to ask yourself is: is performance the issue for you? Will you be running the test condition in a tight loop for example?
Adrian Regan
The question I asked is more about common practices, whether RTTI is commonly used and perceived as acceptable solution by other programmers.
MarcAndreson
I don't believe that you should be looking to avoid RTTI, more, you should look at how you can use it best to your advantage. It is a first class tool in those languages that support it.
Adrian Regan
Ok, thanks for answers and example, but your solution is good for languages with multiple inheritance like C++. I cannot use it since my classes must derive from Base. I think I will consider using RTTI instead.
MarcAndreson
That's the spirit!
Adrian Regan