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


40

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_CONSTANTanzichéThatClass.MY_CONSTANT
  • ogni costante definita una sola volta

Questo approccio è piuttosto una pratica buona o cattiva? Ho voglia di abusare un po 'del concetto di interfacce.

Puoi rispondere in generale sulle interfacce / costanti, ma anche sui test unitari se c'è qualcosa di speciale al riguardo.


La risposta per "È una cattiva pratica avere un'interfaccia che definisce X?", Essendo X qualsiasi cosa che non sia "firme del metodo", è quasi sempre sicuramente "Sì".
T. Sar - Ripristina Monica il

Risposte:


79

Joshua Bloch sconsiglia questo nel suo libro Effective Java :

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 nelle API esportate 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.

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


13

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.


7

Non penso 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 designer inserisce quelle costanti lì è perché ha pensato che sarebbe abbastanza stabile da far parte dell'interfaccia, come lo è getTransparency ().


2

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.


1
le interfacce sono appalti pubblici. I VALORI costanti sono preoccupazioni private, l'interfaccia pubblica dovrebbe esporre al massimo i loro nomi. È meglio lasciarlo a una classe astratta.
jwenting

Casi in questione: javax.naming.Context, javax.ims.Session e centinaia di tali interfacce ...
CMR

2
@jwenting Inoltre, potrebbe un'interfaccia pubblica "at most expose their names", senza esporre i valori?
CMR

dipenderebbe dal linguaggio di programmazione immagino. Nel caso di Java, no.
jwenting

2

Un'azienda in cui ho lavorato ha fatto un uso intensivo delle costanti 1 importate dall'interfaccia . Non mi viene in mente alcun danno.

La domanda che dovresti porti è: quanto è importante lo spazio dei nomi per te? Nel caso delle costanti, è davvero tutto ciò che una classe si comporta. 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 di cui hai bisogno, 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 importparola chiave, intendo solo portare viaimplements MyConstantsInterface


1

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 minimo.

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


Aggiunta di altri collegamenti che fanno riferimento all'importazione statica (1.5): 1. Wikipedia 2. Documenti Oracle che fanno riferimento a @Justinc
Abhijeet

1
So when should you use static import? Very sparingly! Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). In other words, use it when you require frequent access to static members from one or two classes. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Riferimento da Oracle Docs
Abhijeet del

1

No, non è una cattiva pratica generale.

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

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.