Domanda

E 'davvero impossibile nascondere alcune classi in un file jar?

ho voluto non permettere di un'istanza diretta delle classi per mantenere più flessibile. Solo la fabbrica (o una facciata) dovrebbero essere visibili di questo vaso.

C'è un altro modo di risolvere questo problema rispetto alla creazione di due progetti? (Due progetti: il primo contiene le classi (Attuazione) e l'altro riferimenti al primo e contiene la fabbrica, poi solo il secondo farà riferimento)

È stato utile?

Soluzione

Credo che si avrà sia il fallimento compilatore o un'avvertenza se il metodo pubblico factory cercare di tornare qualcosa che è "nascosto".

No, non si può nascondere una classe pubblica senza reimplementare il proprio ClassLoader o utilizzando OSGi o qualcosa di simile.

Che cosa si può fare è quello di separare l'interfaccia API per l'attuazione, per esempio avere un progetto che contiene solo le interfacce e un altro porject che contiene i implmentations. Tuttavia, ancora non è possibile nascondere le classi di implementazione.

Altri suggerimenti

ho la comprensione che non stai cercando di nascondere le classi attuali, basta evitare che la loro costruzione al di fuori di una classe di fabbrica. Questo penso che può essere raggiunto abbastanza facilmente usando pacchetto privata visibilità (default) nei costruttori della classe. L'unica limitazione è che avrete bisogno di avere le classi e la fabbrica nello stesso pacchetto in modo in un medio-grandi cose codebase può ottenere inutilmente complesso.

Se ho capito la tua domanda correttamente, si vorrebbe fare in modo che gli utenti della vostra biblioteca sono costretti ad usare la vostra fabbrica per istanziare i loro oggetti invece di usare i costruttori stessi.

Come la vedo io ci sono due possibilità, una delle quali è sciocco, ma utilizzabile in alcuni, casi specifici, e l'altro è il più pratico e probabilmente modo più comunemente usato di farlo.

  1. Si potrebbe fare tutte le classi in classi interne private del fabbrica. Ciò funzionerebbe se aveste una fabbrica per classe, ma non è certo praticabile se si dispone di un sacco di diverse classi gestite attraverso una fabbrica.
  2. È possibile utilizzare il modificatore di accesso al protected limitare l'accesso alla classe costruttori. Questo è comune pratica quando si utilizza il modello .

offuscamento può aiutare a in qualche modo .

Con classloader standard di un vecchio barattolo di pianura file questo non è possibile. OSGi cas questo concetto di rendere visibile ad un altro fascio soltanto alcuni pacchetti e non altro (cioè la separazione delle api pubblico e implementazione interna).

Se sei usinf eclissi si può far rispettare tali regole con questo

Se ho capito bene quando si dice "non permettere di un'istanza diretta delle classi per mantenere più flessibile", un modello di facciata eseguito correttamente gestirà questo.

Limita i costruttori di tutte le classi che si desidera nascondere a portata pacchetto. Aprire la classe facciata a scopo pubblico.

http://mindprod.com/jgloss/packagescope.html

"Se si dispone di una variabile o metodo la classe che non si desidera che i client della classe accedere direttamente, non dargli un pubblico, protetto o dichiarazione privata. A causa di un supervisione nella progettazione di Java, è non può dichiarare in modo esplicito il default accessibilità “pacchetto”. Altri membri del pacchetto sarà in grado di vedere, ma le classi di fuori del pacchetto Eredita dal tuo, non lo faranno. Il attributo di accessibilità protetta offre un po 'più visibibily. UN metodo protetto è visibile a classi che ereditano, anche se non parte lo stesso pacchetto. Un ambito pacchetto Metodo (default) non lo è. Questo è il unica differenza tra protetti e ambito pacchetto. "

Ci sono due soluzioni per la tua domanda, che non comportano mantenendo tutte le classi nello stesso package.

Il primo è quello di utilizzare il Friend Accessor / Amico pacchetto modello descritto in ( API pratico design, Tulach 2008).

Il secondo è quello di utilizzare OSGi. C'è un articolo qui spiegare come OSGi realizza questo.

Domande correlate: 1 , 2 , 3 , e 4 .

E 'possibile fare queste magie con una classe personalizzata loader ma:

  • la separazione corretta sarà disponibile solo in un progetto organico con la classe loader;
  • è davvero dubbio che lo sforzo per creare tale caricatore è degno.

In tali situazioni vorrei fare qualcosa di simile a quello che si può vedere nel standard di Java. E.g.you vedere javax.xml.stream.XMLInputFactory ma da qualche parte bisogna com.sun.xml.internal.stream.XMLInputFactoryImpl. E 'perfettamente compilabile se si scrive:

new com.sun.xml.internal.stream.XMLInputFactoryImpl()

anche se sarà difficile farlo :-) Con una proprietà di sistema si può controllare l'attuazione effettiva che viene caricato. Per me tale approccio va bene in molte situazioni.

Spero di aver capito bene la tua domanda;)

Cheers!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top