Что хорошего в интерфейсе маркера? - PullRequest
0 голосов
/ 03 июля 2019

Идея или назначение интерфейса маркера звучит для меня совершенно бессмысленно.

При поиске «Сериализуемого класса» в Java я неизбежно пришел к этому понятию «Интерфейс маркера».Я понял, почему и когда его использовать - чтобы пометить / пометить класс, который он предназначен для специального использования, например, для сериализации.

Но самое важное здесь то, что сама причина, я имею в виду идею маркировки класса, чтобы указать, что мы будем использовать его для некоторого использования, но БЕЗ любого метода, кажется мне чепухой.

Если мы хотим наделить класс какими-то особыми значениями, чтобы он мог выполнять задачи, к которым мы стремимся, я твердо верю, что он должен содержать методы, написанные для этих задач.Если внутри ничего нет, то чем он отличается от простого класса?Я даже могу поместить «реализует Сериализуемый» в любые классы, не предназначенные для сериализации ..

Подводя итог - Что ХОРОШО Интерфейса Маркер?

Ответы [ 4 ]

0 голосов
/ 05 июля 2019

Интерфейс маркера используется для добавления поддержки в класс для функциональности, которая не реализована путем переопределения методов.

Когда вы объявляете, что класс реализует Serializable или CloneableНапример, вы разрешаете передавать его методам, которым требуются эти типы, и обещаете, что он придерживается контракта этих типов с помощью принципа подстановки Лискова: https://en.wikipedia.org/wiki/Liskov_substitution_principle

Существует еще кое-что для интерфейсаподразумеваемый контракт, а не только методы, которые он заставляет переопределять.

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

0 голосов
/ 03 июля 2019

Интерфейс маркера действительно следует избегать.

Существуют способы сделать то же самое без интерфейса маркера, как это было бы с интерфейсом маркера, и эти методы определенно следует отдать предпочтение, так как интерфейс маркера рассматривается как нечто вроде запаха кода.

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

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

Там действительно нет необходимости для интерфейса маркера.

0 голосов
/ 03 июля 2019

Интерфейсы маркеров изначально использовались для придания особого значения классу до того, как Java представила аннотации (в JDK 5).Например, интерфейс Serializable был создан в JDK 1.1.С введением аннотаций лучшим подходом - если класс должен быть помечен и не требуются дополнительные методы - является использование аннотаций.

Например, вместо того, чтобы класс реализовывал интерфейс Serializable,в котором нет методов, лучшим подходом было бы создание аннотации @Serializable и применение этой аннотации к классу (обратите внимание, что @Serializable это , а не реальная аннотация, включенная в JDK).

@Serializable
public class Foo {}

Для получения дополнительной информации о том, как создавать и обрабатывать аннотации, см. Создание аннотаций в Java (простите, что я создал эту статью; она включает в себя информацию, которую вам нужно знать о аннотацииобработка, не загромождая этот ответ, копируя его прямо здесь).


Другой подход заключается в изменении мыслительного процесса за интерфейсом маркера и вместо обработки классов и выполнения действий на основе их маркеров, выдвигая логикук самому классу.Например, вместо того, чтобы искать классы с Serializable и затем выполнять логику, логику можно было бы перенести непосредственно в интерфейс Serializable, что позволяет клиентам вызывать логику сериализации непосредственно на объекте.Например:

public interface Serializable {

    public default void writeObject(ObjectOutputStream out) throws IOException {
        // ... default logic ...
    }

    public default void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        // ... default logic ...
    }

    public default void readObjectNoData() throws ObjectStreamException {
        // ... default logic ...
    }
}

Затем сериализуемый объект может быть сериализован напрямую:

public class Foo implements Serializable {}

ObjectOutputStream os = // ... some output stream
Foo foo = new Foo();
foo.writeObject(os);
0 голосов
/ 03 июля 2019

Маркерные интерфейсы используются только для идентификации типа. Кроме этого, нет особого использования для интерфейса маркера.

Например, как вы упомянули, Serializable является хорошим примером интерфейса Marker без какой-либо функции. Классы, которые реализовали Сериализуемый и их объекты, идентифицированы для процесса сериализации JVM.

Так что, если мы хотим определить тип объекта для выполнения какой-либо конкретной операции. Мы можем создавать собственные интерфейсы Marker и использовать их.

...