2015-10-13 8 views
5

Supponiamo che sto modellando diversi animali in Java. Ogni animale ha una combinazione di queste abilità: camminare, nuotare e volare. Per l'esempio, l'abilità impostata è costante.In Java, dovrei usare getter o tag di interfaccia per proprietà costanti?

Posso memorizzare queste informazioni come getter che restituiscono costanti. Per esempio:

public class Penguin implements Animal { 

    public boolean canWalk() { 
     return true; 
    } 

    public boolean canSwim() { 
     return true; 
    } 

    public boolean canFly() { 
     return false; 
    } 

    // implementation... 
} 

Il controllo in fase di esecuzione è quindi:

if (animal.canFly()) { 

    // Fly! 
} 

o posso usare "codifica" interfacce:

public class Penguin implements Animal, Flyer, Swimmer { 

    // implementation... 
} 

Il controllo in fase di esecuzione è quindi:

if (animal instanceof Flyer) { 

    // Fly! 
} 

Quali sono i vantaggi e gli svantaggi di ogni approccio?

risposta

5

Le interfacce di marcatore sono un po 'un anti-modello in Java moderno, richieste in passato perché non c'è modo di aggiungere direttamente i metadati a una classe. L'approccio "moderno" è annotazioni:

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

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

@Flyer @Swimmer 
public class Penguin implements Animal { 
} 

E il controllo runtime:

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

È possibile utilizzare questo approccio se tutto quello che volete sapere è se un Animal ha questa caratteristica, che è di volo e la capacità di nuoto è pura metadata.

Cosa stai cercando di ottenere? Non chiamerei questo OOP, perché l'approccio OOP di solito non è di interrogare le capacità ed eseguire la logica condizionale specifica dell'oggetto, è usare il polimorfismo.

+2

È necessario un parametro per un'interfaccia di annotazione affinché sia ​​disponibile in fase di esecuzione. – Dariusz

+0

@Dariusz Buona cattura! Modificato. – sh0rug0ru

+1

È un malinteso comune che le annotazioni siano una sostituzione delle interfacce marker. _Effective Java Item # 37: utilizza le interfacce marker per definire types_, in particolare indica i vantaggi delle interfacce marker rispetto alle annotazioni. – jaco0646

2

Le funzionalità di walk/swim/fly sono legate al tipo o allo stato? Questa è la vera differenza tra marcatura di classe (tipo) e proprietà (stato).

È necessario notare che una volta contrassegnata una classe non può mai essere "non contrassegnata". Tutte le sottoclassi ne erediteranno. E lo stesso vale per una singola istanza in quanto non può cambiare il suo tipo in modo dinamico (almeno in Java).

Un'altra osservazione è relativa all'astrazione. La marcatura richiede altre API per conoscere i tipi di marcatura (interfaccia, classe o annotazioni). Mentre alcune API devono semplicemente fare affidamento su "interfaccia astratta" (cioè nome del metodo). Le API della convenzione JavaBean sono esempi del genere. E l'integrazione sarà resa più facile rispetto alla codifica di metodi specifici per verificare l'ereditarietà della classe o la presenza di annotazioni.

Per concludere, le capacità statiche come un comando Runnable possono fare affidamento sulla marcatura di classe in cui le dinamiche devono basarsi sullo stato.

Problemi correlati