it-swarm.it

È una cattiva pratica avere un'interfaccia per definire le costanti?

Sto scrivendo un insieme di classi di test junit in Java. Esistono diverse costanti, ad esempio stringhe di cui avrò bisogno in diverse classi di test. Sto pensando a un'interfaccia che li definisce e che ogni classe di test la implementerebbe.

I vantaggi che vedo ci sono:

  • facile accesso alle costanti: MY_CONSTANT invece di ThatClass.MY_CONSTANT
  • ogni costante definita una sola volta

Questo approccio è piuttosto una pratica buona o cattiva? Sento che farlo è un po 'come abusare del concetto di interfacce.

Puoi rispondere in generale a proposito di interfacce/costanti, ma anche di unit test se c'è qualcosa di speciale al riguardo.

45
FabianB

Joshua Bloch sconsiglia questo nel suo libro intitolato Java effettivo:

Che una classe usi internamente alcune costanti è un dettaglio di implementazione. L'implementazione di un'interfaccia costante fa sì che questi dettagli di implementazione perdano nell'API esportata delle classi. Per gli utenti di una classe non ha alcuna conseguenza che la classe implementi un'interfaccia costante. In effetti, potrebbe persino confonderli. Peggio ancora, rappresenta un impegno: se in una versione futura la classe viene modificata in modo da non dover più utilizzare le costanti, deve comunque implementare l'interfaccia per garantire la compatibilità binaria.

Puoi ottenere lo stesso effetto con una classe normale che definisce le costanti e quindi utilizzare import static com.example.Constants.*;

88
matt

Nel nostro caso lo stiamo facendo perché i valori delle costanti rappresentano un contratto per gli stati finali che l'implementazione di un servizio è richiesta per fornire. Inserendo queste costanti nell'interfaccia si specificano gli stati finali come parte del contratto e se l'implementazione dell'interfaccia non li utilizzava non farebbe il suo lavoro.

Alcune costanti sono dettagli di implementazione. A volte non lo sono. Come al solito, un ingegnere deve usare il cervello per decidere cosa fare e non fare affidamento su uno schema o una pratica ampi.

14
user144901

Non credo sia una buona cosa avere interfacce solo per le costanti.

Ma se un'interfaccia che definisce il comportamento (i metodi che implementano le classi dovrebbero implementare) ha costanti, va bene. Se "perde alcuni dettagli dell'implementatore" nell'API, è perché dovrebbe essere così. Perdono anche che l'implementatore implementa i metodi .foo() e .bar().

Prendiamo ad esempio l'interfaccia Java.awt.Transparency. Ha costanti OPAQUE, BITMASK e TRANSLUCENT ma ha anche il metodo .getTransparency().

Se il progettista inserisce quelle costanti lì è perché pensava che sarebbe abbastanza stabile da far parte dell'interfaccia, come lo è .getTransparency().

6

Un'azienda in cui ho lavorato ha fatto un uso intensivo di interfacce importate1 costanti. Non mi viene in mente alcun danno.

La domanda che dovresti porti è, quanto è importante lo spazio dei nomi per te? Nel caso delle costanti, in realtà è tutto ciò che una classe agisce. Se hai migliaia di costanti, potresti non volere tutte quelle costanti sempre disponibili.

La cosa bella delle interfacce è che ti dà il vantaggio di lavorare in entrambi i modi: porta tutti gli spazi dei nomi che ti servono, o nessuno di essi (e accedi esplicitamente, con MyInterface.CONSTANT). Praticamente la stessa cosa di import static MyInterface.*, ma un po 'più ovvio.


1: Se non hai familiarità con Java, non intendo la parola chiave import, intendo solo introdotta tramite implements MyConstantsInterface

2
Nicole

Pensa che sia un punto di vista per lo più popolare nei luoghi in cui prevale il design per contratto.
Le interfacce sono contratti. Inserire le costanti nelle interfacce significa che ogni classe che rispetta il contratto accetta il valore/concetto identificato dalla costante.

2
CMR

No, non è una cattiva pratica generale.

Il punto è che le costanti come qualsiasi altro artefatto dovrebbero essere introdotte secondo le regole della visibilità minima e del livello di astrazione adeguato.

L'uso della sintassi solo perché è possibile è il vero problema.

1
oopexpert

Vengo da uno sfondo che è principalmente influenzato principalmente dal "modo Ada" e dal "modo .Net". Direi di no, che probabilmente non è meglio dichiarare le costanti all'interno delle interfacce. Tecnicamente non è consentito in c #.

Il motivo per cui dico di no è che un'interfaccia è una forma di contratto che definisce il comportamento, non lo stato o la struttura. Una costante implica un qualche tipo di stato (primitivo) o un aspetto dello stato (composito o aggregato).

Posso apprezzare l'impulso di rendere disponibili valori predefiniti e valori predefiniti a tutti coloro che implementano l'interfaccia, ma forse lo stato predefinito sarebbe meglio descritto in un oggetto o modello astratto o di valore, in cui i valori predefiniti avrebbero un contesto almeno minimo.

Per una guida più tecnica: download.Oracle.com/javase/1.5.0/docs/guide/language/static-import.html

1
JustinC