Маркерный интерфейс или логический метод для определения возможностей объекта?

Я разрабатываю большую иерархию Java-классов, некоторые из которых имеют определенное свойство, которое мне интересно запрашивать во время выполнения (свойство определенно относится только к классам, а не к конкретным экземплярам).

Я мог бы создать абстрактный логический метод isFooBar() что подклассы могут быть реализованы, чтобы указать, присутствует свойство или нет:

public abstract class MyBaseClass {
  ...
  public abstract boolean isFooBar();
}

Или в качестве альтернативы я мог бы использовать интерфейс маркера FooBarProperty и сделать instanceof проверьте по интерфейсу:

public class MyConcreteClass extends MyBaseClass implements FooBarProperty {
   ...
}

Или, я думаю, вы могли бы даже использовать аннотацию, предложенную AmitD:

@FooBarAnnotation
public class MyConcreteClass extends MyBaseClass {
   ...
}

Каковы плюсы и минусы каждого метода и какие обычно следует отдавать предпочтение?

2 ответа

Решение

Интерфейсы маркеров наследуются в иерархии классов, поэтому они имеют ограниченные возможности (вы не можете "удалить" этот интерфейс маркеров для какого-то определенного подкласса), и я не могу рекомендовать их (Cloneable является плохим примером этого). Вопрос в том, действительно ли ваша собственность связана с классом объекта, а не с экземпляром? Если это так, аннотации лучше, потому что они не добавляют дополнительные методы в ваши API, и их проще поддерживать - вы просто добавляете / удаляете аннотацию (в случае проверки метода вы должны проверить все подклассы, переопределяют ли они это или нет).

РЕДАКТИРОВАТЬ: в вашем случае я бы задал себе вопрос: является ли мое свойство типа "является постоянным" (применяется для всех экземпляров данного класса) или "видимым" (применяется только для некоторых экземпляров)

В интерфейсах маркеров нет методов. В вашем случае ваш интерфейс имеет метод для получения свойства, и на основании этого вы должны использовать интерфейс. Вы можете просто использовать этот интерфейс для хранения конкретного экземпляра классов, который реализует ваш интерфейс и может вызывать метод, связанный со свойством.

Однако на другом конце маркера используется или отмечен и экземпляр или иерархия, так что он будет иметь право на определенные функции, такие как постоянство.

Другие вопросы по тегам