J'ai du mal à comprendre pourquoi vous devriez développer des bibliothèques internes à utiliser exclusivement pour développer des applications internes. J'apprécie que si je veux utiliser un logiciel écrit par quelqu'un en dehors de l'organisation, il peut m'envoyer ses fichiers d'en-tête et ses fichiers .a ou .so et je peux simplement le lier à mon projet (en supposant qu'ils soient compilés dans le même environnement) .
Mais pourquoi une bibliothèque interne devrait-elle être développée uniquement pour être liée à une application interne lorsque j'ai accès à l'en-tête et aux fichiers d'implémentation et que je peux simplement les inclure dans mon arborescence source et les compiler tous ensemble?
En d'autres termes: si du code source est écrit, comment décidez-vous s'il doit être compilé dans une bibliothèque binaire et lié à votre application ou simplement inclus dans les fichiers source du projet et compilé régulièrement?
Quand je dis «inclure» des fichiers dans chaque projet, je ne veux pas copier et coller chaque fichier dans l'arborescence source du projet en cours de développement. Je veux dire développer un répertoire / bibliothèque (séparé de tout projet) contenant du code source commun qui peut être inclus dans les fichiers d'un projet de la manière habituelle, c'est-à-dire #include.
ps Je parle du développement c / c ++ ici pour plusieurs applications de bureau.
Réponses:
Il existe de nombreuses raisons de créer des bibliothèques et des bibliothèques partagées (dans des fichiers .dll ou .so) même pour un usage interne:
Certaines entreprises ont même une pratique comptable où les projets qui créent des bibliothèques sont remboursés à chaque réutilisation.
la source
Quelques autres raisons possibles qui peuvent s'appliquer à des projets plus importants et non triviaux:
Temps de compilation: d' énormes projets monolithiques C ++ avec des milliers de fichiers, des milliers de classes, de fonctions, etc. peuvent prendre très longtemps à compiler (ce qui nuit à la productivité si vous souhaitez recompiler chaque fois que vous modifiez quelques lignes de code). Les bibliothèques liées statiquement et liées dynamiquement sont compilées indépendamment et n'ont pas besoin d'être recompilées si leur source n'a pas changé.
Séparation logique de modules ou sous-systèmes distincts : les grands systèmes sont généralement plus faciles à gérer si des domaines de fonctionnalité distincts sont placés dans des modules séparés, et les développeurs ne sont pas confrontés à la recherche dans d'énormes dossiers / projets contenant des milliers de fichiers / classes.
Limites entre les développeurs / équipes : les développeurs qui créent simultanément de nouvelles fonctionnalités distinctes peuvent réduire le risque de conflits de fusion s'il est possible que chaque développeur travaille dans des modules différents.
Code qui ne doit pas être publié dans un environnement en direct : par exemple, des bibliothèques de tests unitaires ou des bibliothèques `` fictives '' qui sont utilisées pour les tests des développeurs pour remplacer un composant du système en direct (matériel, API, systèmes distants, bases de données, etc.)
Drapeaux du compilateur : si vous vous trouvez dans une position très malheureuse d'intégration avec une API tierce qui attend un drapeau de compilateur étrange, la bibliothèque peut être une "couche de décontamination" située entre l'API tierce et le reste de l'application.
Fonctionnalités facultatives / optimisation : dans les grands systèmes, une application peut attendre avant de charger certains modules liés dynamiquement dans la mémoire au moment de l'exécution s'ils ne sont pas essentiels à la fonctionnalité de base de l'application.
En général, de nombreux projets internes sont souvent de petites micro-applications qui ne bénéficient pas d'être divisées en bibliothèques distinctes. Si vous travaillez sur un petit projet en tant que développeur seul, vous n'avez peut-être pas besoin de vous soucier de diviser votre code en bibliothèques (pour le moment ...). N'oubliez pas le principe YAGNI .
la source
Votre question d'origine pourrait avoir causé un malentendu ici pour la plupart de ces autres réponses. Étant donné que vous n'avez pas l'intention de copier le code existant entre les projets, mais d'inclure les mêmes fichiers source de différents projets comme références , tout argument de "code en double" devient inutile, ainsi que de nombreux autres arguments présentés.
Notez que c'est parfois (- pas toujours -) une technique sensée . En fait, lorsque vous placez tous les fichiers source que vous souhaitez réutiliser dans plusieurs projets dans un dossier d'inclusion distinct, vous avez également créé une bibliothèque - une bibliothèque de code source, pas une bibliothèque binaire. Surtout en C ++, lors de la création de bibliothèques génériques avec des modèles, il n'est pas inhabituel d'avoir des bibliothèques uniquement en-tête, qui ont juste besoin d'une simple inclusion et d'aucune préparation de liaison séparée.
Donc, je suppose que votre vraie question est - quand construire des bibliothèques de code source, ou quand préférer des bibliothèques binaires précompilées? Dans cette ancienne réponse sur ce site , j'ai discuté de certains avantages et inconvénients des bibliothèques uniquement en-tête, peut-être que cela vous aide. Le principal avantage des bibliothèques de code source est qu'elles ne nécessitent pas d'être compilées avec les mêmes indicateurs de compilateur / éditeur de liens compatibles et d'exécution que l'application qui les utilise. Les inconvénients sont les temps de compilation supplémentaires et la nécessité de donner accès au code source (ce qui n'est évidemment pas un problème pour le type de projets "internes" que vous avez en tête).
la source
Je suis d'accord avec les autres commentateurs lorsqu'ils écrivent que vous ne devez pas dupliquer de code. Dans votre cas, cependant, il semble que vous (ou les personnes avec lesquelles vous travaillez) créez des bibliothèques pour du code qui n'est pas dupliqué ailleurs.
Dans ce cas, je mets en garde contre une généralisation prématurée . Il y a souvent des moments où l'on sent qu'un morceau de code sera réutilisable. Cependant, sans connaître les détails intimes de la façon dont le deuxième cas d'utilisation utilisera un tel code, il est très facile de consacrer plus de temps aux fonctionnalités de «réutilisabilité» qui ne seront pas réellement utiles dans les cas supplémentaires ou de faire des hypothèses qui s'avèrent erronées dans le deuxième cas.
Écrire une "bibliothèque" pour un cas d'utilisation peut se transformer en un exercice très coûteux sans aucun gain --- j'ai été mordu par cela plusieurs fois.
Exemples de coûts:
Ma règle générale est la suivante: ne transformez pas le code en bibliothèque à moins d'avoir au moins 2 emplacements distincts où le code est nécessaire.
la source
Parce que si vous les "incluez simplement dans mon arbre source", vous dupliquez du code .
Le problème avec cela est que vous ne bénéficierez d'aucune amélioration (y compris les corrections de bogues critiques) apportées par le projet à partir duquel vous avez copié le code, et ils ne bénéficieront pas des améliorations que vous apporterez.
Vous pourriez penser que vous pouvez résoudre ce problème en copiant simplement la dernière version du code dans votre arborescence source régulièrement, peut-être même automatisée en utilisant un sous-module dans git ou quelque chose de similaire. Mais alors, vous aurez constamment votre pause de construction en raison de modifications d'API incompatibles. Une bibliothèque, d'autre part, a une API publique "officielle" dont ses développeurs savent qu'elle ne peut pas être modifiée sans coodiner avec les clients.
Enfin, il peut y avoir des raisons techniques - pourrait-il être nécessaire de conserver une partie du code en tant que bibliothèque afin qu'il puisse être chargé en option ou même chargé et déchargé à la demande, et ainsi réduire l'utilisation de la mémoire lorsque la fonctionnalité n'est pas nécessaire?
la source
Je voudrais préciser les coûts de votre solution à long terme.
De toute évidence, l'ajout d'une bibliothèque à un projet a des frais généraux, tous si c'est le premier: les flux de travail doivent être modifiés, parfois même l'infrastructure et certains membres de l'équipe peuvent ne pas l'aimer (au début). Les avantages de votre solution sont donc évidents, car elle impose désormais des coûts moindres .
Cependant, au fur et à mesure que votre projet se développe, les coûts de la "pseudo-bibliothèque" le seront également. Supposons que vous ayez une "pseudo-bibliothèque"
A
utilisée par une application et un testeur d'unité. Chaque fois que vous ajoutez un cpp àA
, vous devez l'ajouter aux deux projets, sinon ils ne seront pas liés.Et si votre "pseudo-bibliothèque" est utilisée par une autre "pseudo-bibliothèque"
B
? Vous devez ajouter votre nouveau cpp dans un tas de projets de plus. Et siB
passer à utiliser une autre bibliothèque? Vous devrez supprimer les cpps deA
tous les projets en fonction uniquement deB
.Tout cela serait gratuit si une vraie bibliothèque était utilisée. La question est donc de savoir combien de cpp sont nécessaires pour justifier le passage à une véritable bibliothèque?
Mais attendez, il y a encore plus de garanties: un développeur n'aime pas ce stupide travail de chasse à tous les projets nécessitant le nouveau cpp et ajoutera son code / ses classes quelque part dans des fichiers déjà existants, ce qui n'est pas une bonne chose dans le long terme.
L'utilisation de la "pseudo-bibliothèque" peut donc être une première étape pour casser un projet monolithique, mais il ne faut pas attendre trop longtemps pour en faire une véritable bibliothèque pour pouvoir utiliser ses avantages.
la source
Si la bibliothèque n'est utilisée que par une seule application, vous n'en aurez probablement pas besoin en tant que bibliothèque distincte.
Si la bibliothèque est utilisée par 3500 applications alors vous absolument faire besoin comme une bibliothèque séparée.
Et s'il y a un bogue dans la bibliothèque et que vous devez le corriger? Ou un changement statutaire ou réglementaire survient, ce qui signifie que vous devez changer le fonctionnement de la bibliothèque?
S'il se trouve dans une bibliothèque distincte, vous pouvez (potentiellement) corriger la bibliothèque, la tester à nouveau et la redéployer et chaque application bénéficie du correctif.
Si ce n'est que dans le code source qui est «local» pour chaque application, vous devez modifier, recréer, tester et redéployer chaque application individuellement . C'est un exercice beaucoup plus important (c'est-à-dire plus coûteux).
la source