标记界面有什么好处?

时间:2019-07-03 02:27:18

标签: design-patterns marker-interfaces

标记界面的想法或目的对我来说完全没有意义。

在Java中搜索“可序列化类”时,我不可避免地想到了“标记接口”这个概念。我知道为什么以及何时使用它-标记/标记类是特殊用途的,例如序列化。

但是这里最重要的是原因本身,我的意思是标记类的想法,以表明我们将使用它作某种用途,但没有任何方法,对我而言似乎是胡说八道。

如果我们想赋予一个类一些特殊的含义,以便它可以执行我们想要的工作,我坚信它应该包含为该工作编写的方法。如果内部没有任何内容,那与普通类又有什么不同呢?我什至可以将“可实现序列化的实现”放到任何不打算序列化的类中。

总结-标记界面有什么优点?

4 个答案:

答案 0 :(得分:0)

标记接口仅用于类型识别。除此之外,标记接口没有特定用途。

例如您提到的Serializable是没有任何功能的Marker接口的一个很好的例子。 JVM确定要实现序列化的类及其对象以进行序列化过程。

因此,如果我们要确定对象类型以执行任何特定操作。我们可以创建自己的Marker接口并使用它。

答案 1 :(得分:0)

标记界面真的应该避免。

在没有标记接口的情况下,有许多方法可以完成与使用标记接口的方法相同的工作,并且绝对应该首选使用这些方法,因为标记接口被认为有点代码味。

在C#中,可以使用可以应用于类的属性。尽管绝对安全,这些操作绝对较慢,因为安全转换的速度相当快,但是有一些方法可以通过例如基于输入类型的缓存来提高速度。

我发现,在许多情况下,使用普通的object而不是期望标记器接口,可能会更加灵活,因为这减轻了实现者的负担。

确实不需要标记界面。

答案 2 :(得分:0)

Marker接口最初用于在Java引入注释之前(在JDK 5中)将特殊含义附加到类。例如,Serializable接口是在JDK 1.1中创建的。随着注释的引入,一种更好的方法(如果需要标记一个类并且不需要其他方法)是使用注释。

例如,代替让类实现没有方法的Serializable接口,一种更好的方法是创建注释@Serializable并将该注释应用于类(注意@Serializable 不是是JDK中包含的真实注释)。

@Serializable
public class Foo {}

有关如何创建和处理批注的更多信息,请参见Creating Annotations in 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);

答案 3 :(得分:0)

标记接口用于为类提供支持,该类不是通过覆盖方法实现的功能。

例如,当您声明一个类实现SerializableCloneable时,即表示您允许将其传递给需要这些类型的方法,并承诺它遵守这些类型的协定通过Liskov替换原理:https://en.wikipedia.org/wiki/Liskov_substitution_principle

接口的隐含契约不仅仅是它使您重写的方法。

Marker接口非常罕见,因为它对于使用接口方法实现的接口所需的功能几乎总是更好。有时,SerializableCloneable就是这种情况,但是由于某种原因,它并不适合该模式。在这些情况下使用标记器接口,因为该接口的其他功能仍然有效。