Wir müssen eine Bibliothek schreiben. Natürlich sollte es nur eine sehr kleine API haben (so breit wie nötig, so klein wie möglich). Die Interna der Bibliothek sind etwas komplex. Daher müssen sie strukturiert werden.
Für die Strukturierung sehe ich derzeit zwei Möglichkeiten:
1. Verwenden Sie Pakete.
Profis: Die Bibliothek kann ordentlich strukturiert werden. Alles an seinem Platz.
Nachteile: Die Verwendung von Klassen über Paketgrenzen hinweg erfordert öffentliche Klassen und erweitert daher die API der gesamten Bibliothek.
2. Verwenden Sie statische innere Klassen in einem Paket.
Profis: Es werden nur sehr wenig öffentliche Dinge (Klassen, Methoden usw.) benötigt.
Nachteile: Klassen werden nur ausgeblendet, um sie zu strukturieren. Dies wäre einer der wenigen Anwendungsfälle, in denen so viele statische innere Klassen verwendet werden. Entwickler sind daran nicht gewöhnt und übersehen sie möglicherweise.
Gibt es einen besseren Weg, um eine kleine API in einer gut strukturierten Bibliothek zu erreichen?
Bearbeiten: Ich habe vergessen zu erwähnen: Es ist für eine Android-Bibliothek. Daher kein Java9.
Antworten:
Ich sehe, was Sie mit 2 machen. Sie verwenden Klassen als Pakete und Pakete als Module, damit Sie sich innerhalb des Pakets isolieren und dennoch innerhalb des Pakets mithilfe von Klassen organisieren können.
Das ist sehr klug. Vorsicht vor klug.
Dadurch werden Sie gezwungen, mehrere Klassen in derselben Quelldatei zu blockieren (was Sie vielleicht bevorzugen), und der Pfad enthält ein Wort mit Großbuchstaben.
Dies zwingt Sie auch dazu, Testcode innerhalb des Pakets zu schreiben, es sei denn, Sie verwenden Reflection, um sich von außen hineinzuhacken.
Andernfalls wird dies funktionieren. Es wird einfach komisch erscheinen.
Menschen sind eher daran gewöhnt , dass innere Klassen wie EntrySet in Hashtable verwendet werden. Es ist privat, daher kann ich es nicht erstellen, aber es implementiert eine öffentliche Schnittstelle, sodass ich einfach über die Schnittstelle mit ihr spreche und mir etwas besorgen kann.
Aber Sie beschreiben Klassen, mit denen ich nicht einmal über eine Schnittstelle sprechen soll. Also keine Schnittstelle für mich. Dies bedeutet, dass ich nichts zu sehen habe und verwirrt bin (es sei denn, Sie geben mir die Quelle).
Das größte Problem, das ich sehe, sind verwirrende Neulinge, die die API warten. Sie können Dokumentationen und Kommentare auf sie werfen, aber seien Sie nicht übergroß, wenn sie keine lesen oder ihnen vertrauen.
Sie haben ein weiteres Muster erstellt, das einen Sprachmangel ausgleicht. Java hat keinen Zugriffsmodifikator, der den Zugriff auf eine Gruppe von Paketen gewährt. Ich habe gehört, dass ein "Modul" -Zugriffsmodifikator vorgeschlagen wurde, sehe aber keine Anzeichen dafür.
Der Standardzugriffsmodifikator (kein Modifikator) wird wahrscheinlich hier verwendet, es sei denn, es macht Ihnen nichts aus, dass ich mich durch die Vererbung einschleiche. In diesem Fall ist er geschützt.
Was Sie wirklich wollen, ist Modulzugriff. Auf diese Weise können Sie Ihre Tests in einem Paket und den Code in einem anderen aufbewahren. Leider haben wir es nicht in Java.
Die meisten Leute machen nur 1 und erweitern die API. Die ordnungsgemäße Verwendung von Schnittstellen entlastet die Implementierung.
Das Hacken, was Sie wollen, in 1 ist noch hässlicher. Schauen Sie sich den Aufrufstapel an und lösen Sie eine Ausnahme aus, wenn das, was Sie angerufen haben, aus einem Paket stammt, das Sie nicht mögen. Eeew.
quelle
Trennen Sie Ihren Code auf jeden Fall in Pakete. Dies wird einen großen Beitrag zur Verbesserung der Wartbarkeit leisten.
Um zu verhindern, dass Endbenutzer auf Dinge zugreifen, die sie nicht sollten, müssen Sie Ihre API in Schnittstelle und Implementierung unterteilen.
Sie können dies im wahrsten Sinne des Wortes tun, indem Sie die gesamte API in Form von Java-Schnittstellen definieren und eine Reihe von Factory-Klassen bereitstellen, um Implementierungsobjekte zu erstellen. Dies ist, was JDBC tut.
Sie können dies auch über Konventionen tun, indem Sie
internal
Pakete erstellen und diese Pakete als implementierungsabhängig dokumentieren und ohne Vorwarnung oder Abwärtskompatibilität ändern.quelle