Question

Est-il vraiment impossible de cacher certaines classes dans un fichier jar?

Je voulais ne pas permettre instanciation directe des classes pour le maintenir plus souple. Seule l'usine (ou une façade) doivent être visibles de ce pot.

Y at-il d'autre moyen que de résoudre ce problème que la création de deux projets? (Deux projets: le premier contient les classes (mise en œuvre) et l'autre des références à la première et contient l'usine, plus tard que le second sera référencé)

Était-ce utile?

La solution

Je pense que vous aurez soit l'échec du compilateur ou un avertissement si votre essai de la méthode d'usine publique pour retourner quelque chose qui est « caché ».

Non, vous ne pouvez pas cacher une classe publique sans réimplémentant votre propre ClassLoader ou en utilisant OSGi ou quelque chose de similaire.

Ce que vous pouvez faire est de séparer api d'interface de la mise en œuvre, par exemple avoir un projet qui ne contient que les interfaces et une autre porject qui contient les implmentations. Cependant, vous ne pouvez toujours pas cacher les classes d'implémentation.

Autres conseils

Je vous comprends ne cherchez pas à cacher les classes réelles, tout simplement empêcher leur construction à l'extérieur d'une classe d'usine. Je pense que ce peut être facilement réalisé en utilisant une visibilité privée paquet (par défaut) dans les constructeurs de classe. La seule limitation est que vous aurez besoin d'avoir les classes et l'usine dans le même paquet donc dans un milieu à de grandes choses codebase peuvent obtenir inutilement complexes.

Si je comprends bien votre question, vous voulez vous assurer que les utilisateurs de votre bibliothèque sont contraints d'utiliser votre usine pour instancier leurs objets plutôt que d'utiliser les constructeurs eux-mêmes.

Comme je le vois, il y a deux possibilités, dont l'un est idiot, mais utilisable dans quelques cas spécifiques, et l'autre est la façon la plus pratique et probablement le plus utilisé de le faire.

  1. Vous pouvez faire toutes vos classes en privé classes internes du usine. Cela fonctionnerait si vous aviez une usine par classe, mais est à peine réalisable si vous avez beaucoup de différentes classes gérées dans une usine.
  2. Vous pouvez utiliser le modificateur d'accès à protected restreindre l'accès à votre classe constructeurs. Cette situation est commune pratique lorsque vous utilisez la href="http://en.wikipedia.org/wiki/Factory_method_pattern#Example" motif .

obscurcissement peut vous aider à en quelque sorte .

Avec classloaders standards un pot bon vieux fichiers cela est impossible. OSGi CAS ce concept de rendre visible à un autre paquet que certains paquets et pas d'autres (à savoir la séparation des api publique et la mise en œuvre interne).

Si vous êtes usinf éclipse vous pouvez appliquer ces règles avec ce

Si je vous comprends bien quand vous dites « ne pas permettre instanciation directe des classes pour le maintenir plus flexible », un motif de façade correctement exécuté sera gérer cela.

Limiter les constructeurs de toutes les classes que vous souhaitez masquer à la portée de l'emballage. Ouvrez la classe de façade à la portée du public.

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

  

"Si vous avez une variable ou méthode   votre classe que vous ne voulez pas les clients   de votre classe accédant directement,   ne donnent pas un organisme public, protégé ou   déclaration privée. En raison d'une   la surveillance dans la conception de Java, vous   ne peut pas déclarer explicitement la valeur par défaut   accessibilité « paquet ». Autres membres   du paquet sera en mesure de le voir,   mais les classes en dehors du package   Hériter de la vôtre, ne sera pas. le   attribut d'accessibilité protégé   offre un peu plus visibibily. UNE   Méthode protégée est visible à   héritant des classes, même pas partie de   le même paquet. Un champ d'application de l'emballage   Procédé (par défaut) est pas. C'est le   seule différence entre la protection et   champ d'application de l'emballage. «

Il y a deux solutions à votre question qui ne concernent pas garder toutes les classes dans le même paquet.

La première est d'utiliser l'accesseur ami / motif ami paquet décrit en ( API pratique design Tulach 2008).

La seconde consiste à utiliser OSGi. Il y a un article ici expliquant comment OSGi accomplit cela.

Questions connexes: 1 , 2 , 3 et 4 .

Vous pouvez faire ces magies avec un chargeur de classe personnalisée, mais:

  • la séparation correcte ne sera disponible que dans un projet personnel avec votre chargeur de classe;
  • il est vraiment douteux que l'effort de créer un tel chargeur est digne.

Dans de telles situations que je ferais quelque chose de semblable à ce que nous pouvons voir dans la norme Java. E.g.you voir javax.xml.stream.XMLInputFactory mais quelque part vous avez com.sun.xml.internal.stream.XMLInputFactoryImpl. Il est parfaitement compilable si vous écrivez:

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

si vous aurez du mal à le faire :-) Avec une propriété de système, vous pouvez contrôler la mise en œuvre réelle qui est en cours de chargement. Pour moi, cette approche est très bien dans de nombreuses situations.

J'espère avoir bien compris votre question;)

Vive!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top