2015-10-13 5 views
5

Angenommen, ich modelliere verschiedene Tiere in Java. Jedes Tier hat eine Kombination dieser Fähigkeiten: gehen, schwimmen und fliegen. Im Beispiel ist die Fähigkeitsmenge konstant.In Java, sollte ich Getter oder Interface-Tagging für konstante Eigenschaften verwenden?

Ich kann diese Informationen als Getter speichern, die Konstanten zurückgeben. Zum Beispiel:

public class Penguin implements Animal { 

    public boolean canWalk() { 
     return true; 
    } 

    public boolean canSwim() { 
     return true; 
    } 

    public boolean canFly() { 
     return false; 
    } 

    // implementation... 
} 

Die Laufzeitprüfung ist dann:

if (animal.canFly()) { 

    // Fly! 
} 

Oder kann ich "Tagging" verwenden Schnittstellen:

public class Penguin implements Animal, Flyer, Swimmer { 

    // implementation... 
} 

Die Laufzeitprüfung ist dann:

if (animal instanceof Flyer) { 

    // Fly! 
} 

Was sind die Vor- und Nachteile von jeder Ansatz?

Antwort

5

Marker-Interfaces sind im modernen Java ein bisschen ein Anti-Pattern, das früher benötigt wurde, da es keine Möglichkeit gab, Metadaten direkt zu einer Klasse hinzuzufügen. Der „moderne“ Ansatz ist Anmerkungen:

@Retention(RetentionPolicy.RUNTIME) 
@interface Flyer { 
} 

@Retention(RetentionPolicy.RUNTIME) 
@interface Swimmer { 
} 

@Flyer @Swimmer 
public class Penguin implements Animal { 
} 

Und die Laufzeitprüfung:

if(Animal.class.isAnnotationPresent(Flyer.class)) { 
    // fly! 
} 

Sie diesen Ansatz verwenden können, wenn alles, was Sie wissen wollen, ist, wenn ein Animal dieses Merkmal hat, das ist Flucht und Schwimmfähigkeit ist reine Metadaten.

Was versuchen Sie zu erreichen? Ich würde diese OOP nicht nennen, weil der OOP-Ansatz normalerweise keine Fähigkeiten abfragt und objektspezifische konditionale Logik ausführt, sondern Polymorphismus.

+2

Sie benötigen einen Parameter für eine Annotationsschnittstelle, damit er zur Laufzeit verfügbar ist. – Dariusz

+0

@Dariusz Guter Fang! Bearbeitet. – sh0rug0ru

+1

Es ist ein häufiges Missverständnis, dass Annotationen ein Ersatz für Marker-Interfaces sind. _Effective Java Item # 37: Verwenden Sie Marker-Interfaces, um types_ zu definieren, und weisen Sie auf die Vorteile von Marker-Interfaces gegenüber Annotationen hin. – jaco0646

2

Sind Walk/Swim/Fly-Fähigkeiten im Zusammenhang mit Art oder Zustand? Dies ist der wirkliche Unterschied zwischen Klassenmarkierung (Art) und Eigenschaft (Zustand).

Sie müssen beachten, dass einmal markierte Klassen nicht "nicht markiert" werden können. Alle Unterklassen erben von ihm. Das Gleiche gilt für eine einzelne Instanz, da sie ihren Typ (zumindest in Java) nicht dynamisch ändern kann.

Eine weitere Bemerkung bezieht sich auf die Abstraktion. Die Markierung erfordert, dass andere APIs über Ihre Markierungstypen (Schnittstelle, Klasse oder Anmerkungen) Bescheid wissen. Während einige APIs nur auf "abstrakte Schnittstelle" (dh Methodenname) angewiesen sind. JavaBean-Konvention bewusste APIs sind solche Beispiele. Und die Integration wird einfacher sein als das Codieren bestimmter Methoden, um nach Klassenvererbung oder Annotationspräsenz zu suchen.

Zusammenfassend können statische Fähigkeiten wie ein Runnable Befehl auf Klassenmarkierung verlassen, wo sich dynamische auf Zustand verlassen müssen.

Verwandte Themen