Klassen in einer JAR-Datei ausblenden

8

Ist es wirklich unmöglich, einige Klassen in einer JAR-Datei zu verstecken?

Ich wollte die direkte Instanziierung der Klassen nicht zulassen, um sie flexibler zu halten. Nur die Fabrik (oder eine Fassade) sollte von diesem Glas sichtbar sein.

Gibt es einen anderen Weg, als dieses Problem zu lösen, als zwei Projekte zu erstellen? (Zwei Projekte: das erste enthält die Klassen (Implementierung) und das andere verweist auf das erste und enthält die Factory; später wird nur auf das zweite verwiesen)

    
nrainer 21.01.2011, 14:05
quelle

8 Antworten

3

Ich denke, Sie haben entweder einen Compilerfehler oder eine Warnung, wenn Ihre öffentliche Factory-Methode versucht, etwas zurückzugeben, was "versteckt" ist.

Nein, Sie können eine öffentliche Klasse nicht ausblenden, ohne Ihre eigene ClassLoader erneut einzufügen oder OSGi oder ähnliches zu verwenden.

Was Sie tun können, ist, Schnittstellen-API von der Implementierung zu trennen, z. haben ein Projekt, das nur die Schnittstellen enthält und ein anderes Projekt, das die Implementierungen enthält. Sie können die Implementierungsklassen jedoch immer noch nicht ausblenden.

    
gigadot 21.01.2011, 14:20
quelle
5

Ich verstehe, dass Sie nicht versuchen, die tatsächlichen Klassen zu verstecken, sondern nur ihre Konstruktion außerhalb einer Fabrikklasse verhindern. Dies kann, glaube ich, sehr leicht erreicht werden, indem die private Sichtbarkeit der Pakete in den Klassenkonstruktoren verwendet wird. Die einzige Einschränkung ist, dass Sie die Klassen und die Factory im gleichen Paket haben müssen, also in einer mittleren bis großen Codebasis können die Dinge unnötig komplex werden.

    
Mikko Wilkman 21.01.2011 14:19
quelle
3

Wenn ich Ihre Frage richtig verstehe, möchten Sie sicherstellen, dass Benutzer Ihrer Bibliothek gezwungen sind, Ihre Factory zu verwenden, um ihre Objekte zu instanziieren, anstatt die Konstruktoren selbst zu verwenden.

Wie ich sehe, gibt es zwei Möglichkeiten, von denen eine doof ist, aber in wenigen, spezifischen Fällen brauchbar ist, und die andere ist die praktischste und wahrscheinlich am häufigsten verwendete Art, dies zu tun.

  1. Du könntest alle deine Klassen machen private innere Klassen der Fabrik. Das würde funktionieren, wenn du es hättest eine Fabrik pro Klasse, ist aber kaum praktikabel, wenn Sie viel haben verschiedene Klassen werden verwaltet durch eine Fabrik.
  2. Sie könnten den Zugriffsmodifizierer protected auf verwenden Beschränken Sie den Zugriff auf Ihre Klasse Konstruktoren. Das ist üblich üben Sie , wenn Sie die -Fabrik verwenden Muster .
Mia Clarke 21.01.2011 14:19
quelle
2

Verschleierung kann Ihnen irgendwie helfen.

>     
Jigar Joshi 21.01.2011 14:07
quelle
2

Mit Standard Classloadern ist eine einfache alte jar Dateien das ist nicht möglich. OSGi ist dieses Konzept, um nur einige Pakete und nicht andere Pakete sichtbar zu machen (d. H. Trennung von öffentlicher API und interner Implementierung).

Wenn Sie sich nicht entscheiden, können Sie solche Regeln mit diesem

erzwingen     
lweller 21.01.2011 14:09
quelle
1

Wenn ich Sie richtig verstehe, wenn Sie sagen, "um die direkte Instantiierung der Klassen nicht zuzulassen, um sie flexibler zu halten", wird ein korrekt ausgeführtes Fassadenmuster damit umgehen.

Beschränken Sie die Konstruktoren aller Klassen, die Sie ausblenden möchten, in den Paketbereich. Öffnen Sie die Fassadenklasse für den öffentlichen Bereich.

Ссылка

  

"Wenn Sie eine Variable oder Methode in haben   Ihre Klasse, dass Sie keine Kunden wollen   der Klasse, auf die direkt zugegriffen wird,   gib es nicht öffentlich, geschützt oder   private Erklärung. Aufgrund eines   Aufsicht im Design von Java, Sie   kann den Standard nicht explizit deklarieren   "Paket" Zugänglichkeit. Andere Mitglieder   des Pakets wird es sehen können,   aber Klassen außerhalb des Pakets, das   von dir erben, nicht. Das   geschütztes Zugriffsattribut   bietet etwas mehr sichtbar. EIN   geschützte Methode ist sichtbar für   Klassen erben, auch nicht Teil von   das gleiche Paket. Ein Paketumfang   (Standard) Methode ist nicht. Das ist das   einziger Unterschied zwischen geschütztem und   Paketumfang. "

    
Speck 21.01.2011 14:19
quelle
1

Es gibt zwei Lösungen für Ihre Frage, bei denen nicht alle Klassen im selben Paket enthalten sind.

Die erste besteht darin, das Friend Accessor / Friend Package -Muster zu verwenden, das in (Practical API Design, Tulach 2008 ).

Die zweite Möglichkeit ist die Verwendung von OSGi. Es gibt einen Artikel hier , der erklärt, wie OSGi dies erreicht.

Verwandte Fragen: 1 , 2 , 3 und 4 .

    
Jeff Axelrod 27.05.2011 15:41
quelle
0

Du kannst solche Magie mit einem benutzerdefinierten Klassenlader machen, aber:

  • die korrekte Trennung ist nur in einem Projekt verfügbar, das mit Ihrem Klassenlader besetzt ist;
  • es ist wirklich zweifelhaft, dass der Aufwand, solch einen Lader zu erstellen, wert ist.

In solchen Situationen würde ich etwas tun, was dem im Standard-Java entspricht. Z. B. sehen Sie javax.xml.stream.XMLInputFactory , aber irgendwo haben Sie com.sun.xml.internal.stream.XMLInputFactoryImpl . Es ist perfekt kompilierbar, wenn Sie schreiben:

%Vor%

obwohl Sie es kaum tun werden :-) Mit einer Systemeigenschaft können Sie die tatsächliche Implementierung steuern, die geladen wird. Solcher Ansatz ist mir in vielen Situationen gut.

Ich hoffe ich habe deine Frage richtig verstanden;)

Prost!

    
Lachezar Balev 21.01.2011 14:19
quelle