In Java, should getters or interface tags be used for persistent properties?

Suppose I model different animals in Java. Each animal has some combination of these abilities: to walk, swim and fly. For example, the set of features is permanent.

I can store this information as getters that return constants. For instance:

public class Penguin implements Animal { public boolean canWalk() { return true; } public boolean canSwim() { return true; } public boolean canFly() { return false; } // implementation... } 

Runtime Check:

 if (animal.canFly()) { // Fly! } 

Or I can use the tagging interfaces:

 public class Penguin implements Animal, Flyer, Swimmer { // implementation... } 

Runtime Check:

 if (animal instanceof Flyer) { // Fly! } 

What are the advantages and disadvantages of each approach?

+5
source share
2 answers

Token interfaces are slightly anti-patterns in modern Java, required in earlier times due to the lack of the ability to directly add metadata to the class. The β€œmodern” approach is annotations:

 @Retention(RetentionPolicy.RUNTIME) @interface Flyer { } @Retention(RetentionPolicy.RUNTIME) @interface Swimmer { } @Flyer @Swimmer public class Penguin implements Animal { } 

And checking the runtime:

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

You can use this approach if all you want to know is that Animal has this trait, that is, the ability to fly and swim is pure metadata.

What are you trying to achieve? I would not call this OOP, because the OOP approach, as a rule, does not request opportunities and does not execute conditional logic, but uses polymorphism.

+5
source

Are walking / swimming / flying opportunities related to goodness or condition? This is the real difference between class labeling (kind) and property (state).

You should note that a once-marked class can never be "unlabeled." All subclasses inherit from it. And the same applies to a single instance, since it cannot dynamically change its type (at least in Java).

Another remark is related to abstraction. Labeling requires other APIs to be aware of your labeling types (interface, class, or annotations). While some APIs just have to rely on an "abstract interface" (that is, a method name). Such examples are JavaBean compatible APIs. And integration will be easier than coding certain methods to check for class inheritance or the presence of annotations.

In conclusion, static features such as the Runnable command can rely on labeling classes in which dynamic must rely on state.

+2
source

Source: https://habr.com/ru/post/1233590/


All Articles