Come incapsulare le classi interne in un'API scritta in Java?

7

Dobbiamo scrivere una biblioteca. Ovviamente, dovrebbe avere solo un'API molto piccola (ampia quanto necessaria quanto più piccola possibile). Gli interni della biblioteca sono piuttosto complessi. Pertanto, hanno bisogno di strutturazione.

Per la strutturazione attualmente vedo due modi:

1. usa i pacchetti.

pros: la libreria può essere strutturata in modo ordinato. Tutto al suo posto.

contro: l'uso delle classi attraverso i bordi dei pacchetti richiede classi pubbliche e quindi amplia l'API dell'intera libreria.

2. usa le classi interne statiche, tutto in un unico pacchetto.

pros: servono solo pochissime cose pubbliche (classi, metodi, ecc.)

contro: le classi sono nascoste solo per strutturarle. Questo sarebbe uno dei pochissimi casi d'uso in cui sono utilizzate così tante classi interne statiche. Gli sviluppatori non sono abituati e potrebbero ignorarli.

Esiste un modo migliore per ottenere una piccola API in una libreria ben strutturata?

Modifica: ho dimenticato di menzionare: è per una libreria Android. Pertanto, non java9.

    
posta Markus Frauenfelder 01.12.2016 - 14:50
fonte

2 risposte

2

Vedo ciò che stai facendo con 2. Stai usando le classi come pacchetti e pacchetti come moduli in modo da poterti isolare all'interno del pacchetto ma comunque organizzarlo all'interno del pacchetto usando le classi.

È molto intelligente. Attenzione ai furbi.

Questo ti costringerà ad inceppare più classi nello stesso file sorgente (che potresti preferire) e il percorso avrà una parola in maiuscolo.

Questo ti costringerà anche a scrivere qualsiasi codice di test all'interno del pacchetto, a meno che non usi la riflessione per entrare dall'esterno.

Altrimenti, funzionerà. Sembrerà strano.

Le persone sono più abituate alle classi interne che vengono utilizzate come EntrySet in Hashtable . È privato quindi non posso crearlo ma implementa un'interfaccia pubblica, quindi mi limito a parlarci attraverso l'interfaccia e ne ho preso uno per me.

Ma stai descrivendo classi alle quali non vuoi che parli anche attraverso un'interfaccia. Quindi nessuna interfaccia per me. Ciò significa che non ho nulla da guardare e da cui essere confuso (a meno che tu non mi fornisca la fonte).

Il problema più grosso che prevedo sono i neofiti confusi che mantengono l'API. Puoi pubblicare documentazione e commenti, ma non essere superquisiti quando non leggono o non si fidano di nessuno dei due.

Hai creato un altro pattern che compensa la mancanza della lingua. Java non ha modificatore di accesso che garantisce l'accesso a un gruppo di pacchetti. Ho sentito che un modificatore di accesso al "modulo" è stato proposto ma non vedo alcun segno che ciò accada.

Il modificatore di accesso predefinito (nessun modificatore) è probabilmente quello che userai qui, a meno che non ti dispiaccia che io entri di nascosto attraverso l'ereditarietà, nel qual caso protetto.

Modifier        Class     Package   Subclass  World
public          Y         Y         Y         Y
protected       Y         Y         Y         N
no modifier     Y         Y         N         N
private         Y         N         N         N 

Quello che vuoi veramente è l'accesso al modulo. In questo modo è possibile mantenere i test in un pacchetto e il codice in un altro. Purtroppo non ce l'abbiamo in Java.

La maggior parte delle persone fa solo 1 ed espande l'API. L'uso corretto delle interfacce mantiene la pressione sull'implementazione.

L'hacking di ciò che vuoi in 1 è ancora più brutto. Sbircia lo stack delle chiamate e genera un'eccezione ogni volta che ti chiamano da un pacchetto che non ti piace. Eeew.

    
risposta data 01.12.2016 - 23:08
fonte
2

Con ogni mezzo, separa il tuo codice in pacchetti. Servirà molto per migliorare la manutenibilità.

Per impedire agli utenti di accedere a cose che non dovrebbero, devi separare la tua API in interfaccia e implementazione.

Puoi farlo letteralmente, definendo l'intera API in termini di interfacce Java e fornendo un certo numero di classi factory per produrre oggetti di implementazione. Questo è ciò che fa JDBC.

Oppure puoi farlo tramite convenzione, creando pacchetti internal e documentando tali pacchetti come dipendenti dall'implementazione e soggetti a modifiche senza preavviso o compatibilità con le versioni precedenti.

    
risposta data 01.12.2016 - 19:15
fonte

Leggi altre domande sui tag