RTTI против дополнительных методов - PullRequest
2 голосов
/ 30 июля 2010

Некоторые из моих классов должны рассматриваться по-разному.Какое решение лучше:

  1. Ввести новый интерфейс в мою иерархию классов и проверить, реализует ли его класс или нет, используя RTTI (идентификация времени выполнения)
  2. Добавить метод, который возвращает логическое значениезначение, которое указывает, должен ли этот класс обрабатываться нормально или заслуживает особого отношения

Следующие примеры иллюстрируют вышеуказанные ситуации:

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 Ответ

1 голос
/ 30 июля 2010

Если «причина» обращения с классом по-другому - это проектное решение, пометьте его как подпись интерфейса, как в решении 1.

Если есть вероятность, что какое-то состояние в вашем приложении будет регулировать это, используйте решение 2.

И примером этого является интерфейс java.io.Serializable без методов или полей, который используется для идентификации реализаций, которые сериализуются. Во время разработки вы решаете, был ли объект сериализуем.

Примечание о производительности instanceof , после дополнительного комментария.

Вы также можете посмотреть на использование Аннотации в качестве альтернативы ...

- РЕДАКТИРОВАТЬ ПОСЛЕ КОММЕНТАРИИ НА ПРАВЛЕНИИ ---

Если вы действительно хотите не отказываться от экземпляра (который очень быстр) или аннотаций, вы можете сделать это ..

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; }
}

Теперь расширьте все, что подходит ....

...