Ich habe Schwierigkeiten zu verstehen, warum Sie interne Bibliotheken entwickeln sollten, die ausschließlich für die Entwicklung interner Anwendungen verwendet werden. Ich weiß zu schätzen, dass wenn ich Software verwenden möchte, die jemand außerhalb des Unternehmens geschrieben hat, er mir seine Header-Dateien und .a oder .so-Dateien senden kann und ich sie einfach mit meinem Projekt verknüpfen kann (vorausgesetzt, sie werden in derselben Umgebung kompiliert). .
Aber warum sollte eine interne Bibliothek entwickelt werden, um mit einer internen Anwendung verknüpft zu werden, wenn ich Zugriff auf die Header- und Implementierungsdateien habe und sie einfach in meinen Quellbaum aufnehmen und alle zusammen kompilieren kann?
Mit anderen Worten: Wenn ein Quellcode geschrieben wird, wie entscheiden Sie, ob er in eine Binärbibliothek kompiliert und mit Ihrer Anwendung verknüpft oder nur in die Quelldateien des Projekts aufgenommen und regelmäßig kompiliert werden soll?
Wenn ich in jedem Projekt "Dateien einschließen" sage, möchte ich nicht jede Datei kopieren und in den Quellbaum des aktuell entwickelten Projekts einfügen. Ich meine, ein Verzeichnis / eine Bibliothek (getrennt von jedem Projekt) zu entwickeln, die allgemeinen Quellcode enthält, der auf die übliche Weise in die Dateien eines Projekts aufgenommen werden kann, dh #include.
ps Ich spreche hier von der C / C ++ - Entwicklung für mehrere Desktopanwendungen.
Antworten:
Es gibt zahlreiche Gründe, Bibliotheken und gemeinsam genutzte Bibliotheken (in DLL- oder SO-Dateien) auch für den internen Gebrauch zu erstellen :
Einige Unternehmen haben sogar eine Buchhaltungspraxis, bei der Projekte, die Bibliotheken erstellen, bei jeder Wiederverwendung eine Erstattung erhalten.
quelle
Einige andere mögliche Gründe, die für größere, nicht triviale Projekte gelten können:
Kompilierungszeiten: Das Kompilieren riesiger monolithischer C ++ - Projekte mit Tausenden von Dateien, Tausenden von Klassen, Funktionen usw. kann sehr lange dauern (was die Produktivität beeinträchtigt, wenn Sie jedes Mal neu kompilieren möchten, wenn Sie einige Codezeilen ändern). Statisch verknüpfte und dynamisch verknüpfte Bibliotheken werden unabhängig voneinander kompiliert und müssen nicht neu kompiliert werden, wenn sich ihre Quelle nicht geändert hat.
Logische Trennung verschiedener Module oder Subsysteme : Große Systeme sind in der Regel einfacher zu verwalten, wenn unterschiedliche Funktionsbereiche in separaten Modulen angeordnet sind und Entwickler nicht mit der Suche in riesigen Ordnern / Projekten mit Tausenden von Dateien / Klassen konfrontiert sind.
Grenzen zwischen Entwicklern / Teams : Entwickler, die gleichzeitig separate neue Funktionen erstellen, können das Potenzial für Zusammenführungskonflikte verringern, wenn jeder Entwickler in verschiedenen Modulen arbeiten kann.
Code, der nicht in eine Live-Umgebung freigegeben werden darf : Zum Beispiel Unit-Test-Bibliotheken oder Mock-Bibliotheken, die für Entwicklertests verwendet werden, um eine Live-Systemkomponente (Hardware, APIs, Remote-Systeme, Datenbanken usw.) zu ersetzen.
Compiler-Flags : Wenn Sie sich in der sehr unglücklichen Lage befinden, in die API eines Drittanbieters zu integrieren, die ein seltsames Compiler-Flag erwartet, kann die Bibliothek eine "Dekontaminationsschicht" sein, die sich zwischen der API des Drittanbieters und dem Rest der Anwendung befindet.
Optionale Funktionen / Optimierung : In großen Systemen kann eine Anwendung warten, bevor bestimmte dynamisch verknüpfte Module zur Laufzeit in den Speicher geladen werden, wenn sie für die Grundfunktionalität der Anwendung nicht kritisch sind.
Im Allgemeinen handelt es sich bei vielen internen Projekten häufig um kleine Mikro-Apps, die nicht davon profitieren, in separate Bibliotheken aufgeteilt zu werden. Wenn Sie als Einzelentwickler an einem winzigen Projekt arbeiten, müssen Sie sich (noch) keine Gedanken über die Aufteilung Ihres Codes in Bibliotheken machen. Vergessen Sie nicht das YAGNI-Prinzip .
quelle
Ihre ursprüngliche Frage könnte hier bei den meisten dieser anderen Antworten zu einem Missverständnis geführt haben. Da Sie nicht beabsichtigen, vorhandenen Code projektübergreifend zu kopieren , sondern dieselben Quelldateien aus verschiedenen Projekten als Referenzen einzuschließen , werden alle Argumente für "doppelten Code" sowie viele andere Argumente sinnlos.
Beachten Sie, dass dies manchmal (- nicht immer -) eine sinnvolle Technik ist . Wenn Sie alle Quelldateien, die Sie projektübergreifend wiederverwenden möchten, in einem separaten Include-Ordner ablegen, haben Sie bereits eine Bibliothek erstellt - eine Quellcodebibliothek, keine binäre Bibliothek. Insbesondere in C ++ ist es beim Erstellen generischer Bibliotheken mit Vorlagen nicht ungewöhnlich, dass nur Header-Bibliotheken vorhanden sind, für die lediglich ein einfaches Include erforderlich ist, und keine separaten Verknüpfungsvorbereitungen.
Ihre eigentliche Frage ist also, wann Sie Quellcode-Bibliotheken erstellen oder wann Sie vorkompilierte Binärbibliotheken bevorzugen. In dieser älteren Antwort auf dieser Site habe ich einige Vor- und Nachteile von Nur-Header-Bibliotheken besprochen. Vielleicht hilft es Ihnen. Der Hauptvorteil von Quellcode-Bibliotheken besteht darin, dass sie nicht mit derselben Laufzeit und / oder kompatiblen Compiler- / Linker-Flags kompiliert werden müssen wie die Anwendung, die sie verwendet. Die Nachteile sind die zusätzlichen Kompilierungszeiten und die Anforderung, Zugriff auf den Quellcode bereitzustellen (was offensichtlich kein Problem für die Art von "internen" Projekten ist, an die Sie denken).
quelle
Ich stimme anderen Kommentatoren zu, wenn sie schreiben, dass Sie keinen Code duplizieren sollten. In Ihrem Fall scheinen Sie (oder die Personen, mit denen Sie arbeiten) Bibliotheken für Code zu erstellen, der an keiner anderen Stelle dupliziert wird.
In diesem Fall warne ich vor vorzeitiger Verallgemeinerung . Es gibt oft Zeiten, in denen man den Eindruck hat, dass ein Teil des Codes wiederverwendbar ist. Ohne die genauen Details darüber zu kennen, wie der zweite Anwendungsfall solchen Code verwendet, ist es jedoch sehr einfach, zusätzliche Zeit für "Wiederverwendbarkeit" -Funktionen aufzuwenden, die in den zusätzlichen Fällen nicht wirklich nützlich sind, oder Annahmen zu treffen, die sich als falsch erweisen der zweite Fall.
Das Schreiben einer "Bibliothek" für einen Anwendungsfall kann zu einer sehr teuren Übung werden, ohne dass sich dies auszahlt. Ich bin mehrmals davon gebissen worden.
Beispielkosten:
Meine allgemeine Regel lautet: Machen Sie keinen Code zu einer Bibliothek, es sei denn, ich habe mindestens zwei separate Stellen, an denen der Code benötigt wird.
quelle
Denn wenn Sie "sie nur in meinen Quellbaum aufnehmen", duplizieren Sie Code .
Das Problem dabei ist, dass Sie weder von Verbesserungen (einschließlich kritischer Bugfixes) des Projekts profitieren, von dem Sie den Code kopiert haben, noch von Verbesserungen, die Sie vornehmen.
Sie könnten denken, dass Sie dieses Problem lösen können, indem Sie einfach die neueste Version des Codes regelmäßig in Ihren Quellbaum kopieren, vielleicht sogar automatisiert, indem Sie ein Submodul in Git oder etwas Ähnlichem verwenden. Aber dann wird Ihre Build-Unterbrechung aufgrund inkompatibler API-Änderungen ständig unterbrochen. Eine Bibliothek hingegen verfügt über eine "offizielle" öffentliche API, von der die Entwickler wissen, dass sie nicht ohne Zusammenarbeit mit Clients geändert werden kann.
Schließlich kann es technische Gründe geben - könnte es notwendig sein, einen Teil des Codes als Bibliothek beizubehalten, damit er optional geladen oder bei Bedarf sogar geladen und entladen werden kann, und so die Speichernutzung zu reduzieren, wenn die Funktionalität nicht benötigt wird?
quelle
Ich möchte auf die Kosten eingehen, die Ihre Lösung auf längere Sicht hat.
Das Hinzufügen einer Bibliothek zu einem Projekt hat natürlich einen gewissen Overhead, alles oben, wenn es das erste ist: Workflows müssen geändert werden, manchmal sogar die Infrastruktur, und einige Teammitglieder mögen es möglicherweise (zuerst) nicht. Die Vorteile Ihrer Lösung liegen also auf der Hand, da sie jetzt weniger Kosten verursacht .
Wenn Ihr Projekt wächst, steigen jedoch auch die Kosten für die "Pseudobibliothek". Angenommen, Sie haben eine "Pseudobibliothek",
A
die von einer Anwendung und einem Unit-Tester verwendet wird. Jedes Mal, wenn Sie eine CPP hinzufügenA
, müssen Sie sie beiden Projekten hinzufügen, da sie sonst nicht verknüpft werden.Was ist, wenn Ihre "Pseudobibliothek" von einer anderen "Pseudobibliothek" verwendet wird
B
? Sie müssen Ihre neue CPP in einer Reihe von Projekten mehr hinzufügen. Und wenn SieB
wechseln, um eine andere Bibliothek zu verwenden? Sie müssen die cppsA
in allen Projekten nur abhängig von löschenB
.Dies alles wäre kostenlos, wenn eine echte Bibliothek verwendet würde. Die Frage ist also, wie viele cpps benötigt werden, um den Umzug in eine echte Bibliothek zu rechtfertigen.
Aber warten Sie, es gibt noch mehr Sicherheiten: Ein Entwickler mag diese blöde Arbeit nicht, alle Projekte zu jagen, die den neuen CPP benötigen, und fügt seinen Code / seine Klassen irgendwo in bereits vorhandene Dateien ein, was in nicht gut ist auf lange Sicht.
Die Verwendung der "Pseudobibliothek" kann also ein erster Schritt sein, um ein monolithisches Projekt aufzubrechen. Sie sollten jedoch nicht zu lange warten, um es zu einer echten Bibliothek zu machen, um seine Vorteile nutzen zu können.
quelle
Wenn die Bibliothek immer nur von einer Anwendung verwendet wird, benötigen Sie sie wahrscheinlich nicht als separate Bibliothek.
Wenn die Bibliothek von 3.500 Anwendungen verwendet wird , benötigen Sie sie unbedingt als separate Bibliothek.
Was ist, wenn es einen Fehler in der Bibliothek gibt und Sie ihn beheben müssen? Oder einige gesetzliche oder regulatorische Änderung kommt das bedeutet , Sie haben , um die Art und Weise ändern sich die Bibliothek funktioniert?
Wenn es sich in einer separaten Bibliothek befindet, können Sie die Bibliothek (möglicherweise) reparieren, erneut testen und erneut bereitstellen, und jede Anwendung profitiert von der Korrektur.
Wenn es sich nur um Quellcode handelt, der für jede Anwendung "lokal" ist, müssen Sie jede Anwendung einzeln ändern, neu erstellen, erneut testen und erneut bereitstellen . Das ist eine viel größere (dh teurere) Übung.
quelle