Accélérer la collaboration et le développement Agile avec la componentisation
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019
Votre produit réussit, votre organisation augmente et il est temps de monter en puissance votre codebase pour répondre à cette réussite. Au fur et à mesure que vous effectuez un scale-out des 2 à 3 équipes travaillant dans une base de code unique sur un seul produit, vous pouvez vous poser des questions telles que :
Comment mes équipes peuvent-elles partager efficacement des composants réutilisables ?
Comment faire permettre à mes équipes de fonctionnalités d’itérer rapidement sans passer au travail d’autres équipes ?
Comment faire donner à mes équipes l’autonomie pour itérer au rythme qui leur convient ?
Les équipes à n’importe quel stade peuvent tirer parti de la prise en compte de ces questions. Si vous êtes une équipe établie avec une base de code héritée, vous pouvez poser ces mêmes questions que vous êtes invité à fournir plus de valeur, plus rapidement que jamais. Quelle que soit votre situation, la componentisation peut vous aider à créer une base de code qui s’adapte à la taille de votre équipe et à la vitesse du développement d’aujourd’hui.
Dans cet article, nous allons découvrir comment la composition binaire via Azure Artifacts peut vous aider à gérer et partager vos dépendances externes, vos logiciels open source et vos composants partagés isolés.
Composants et composition
La componentisation est le processus de division et d’organisation de votre produit en composants distincts. La plupart des projets .NET ont déjà une notion de composants sous la forme de projets au sein de la solution. Par exemple, un site web de base peut se composer d’un composant frontal, d’un composant d’accès aux données et d’un composant de stockage de modèle/de données.
Composition source
À mesure que votre produit augmente, la solution et le modèle de projet peuvent devenir inefficaces. Les modifications prennent plus de temps pour intégrer et sont plus difficiles à fusionner, la génération devient plus lente et les composants commencent à passer d’un projet unique à plusieurs projets. En règle générale, c’est le point auquel les équipes commencent à diviser ces ensembles de projets connexes en solutions distinctes.
Une fois que vous avez dépassé une seule solution, la façon dont vous composantez devient une question intéressante. Nous avons commencé avec la composition source, où chaque composant est référencé via une référence de projet dans Visual Studio. La composition source est possible tant que votre source vit dans une limite de composition unique : une solution unique au sein d’un référentiel source unique.
Malheureusement, ces références de projet commencent à se décomposer lorsque plusieurs solutions sont impliquées. À ce stade, lorsque la solution A dépend de la solution B, elle doit faire référence aux fichiers binaires générés (tels que les DLL) générés par la solution B . Il s’agit d’une composition binaire.
En conséquence, ces fichiers binaires doivent maintenant être créés et mis à la disposition de la solution A avant de pouvoir générer correctement. Plusieurs solutions s’offrent à vous :
Vous pouvez les case activée dans le contrôle de code source. Selon votre système de contrôle de code source, les fichiers binaires peuvent rapidement buller la taille de votre dépôt, ralentissant les temps d’attente case activée et les performances générales du dépôt. Si vous commencez à travailler dans des branches, plusieurs équipes peuvent finir par introduire le même binaire dans différentes versions, ce qui entraîne des conflit de fusion difficiles.
Vous pouvez également les héberger sur un partage de fichiers, même si cette approche présente certaines limitations. Les partages de fichiers n’ont pas d’index pour les recherches rapides, et ils ne fournissent pas de protection contre le remplacement d’une version à l’avenir.
Composition du package
Les packages répondent à la plupart des défis liés au référencement des fichiers binaires. Au lieu de les case activée en source, vous pouvez avoir une solution B produire ses fichiers binaires en tant que packages NuGet qu’une autre solution A peut ensuite consommer. Si la solution A et la solution B sont conservées en tant que composants distincts, où les modifications simultanées entre A et B sont rares, la composition de package est un excellent moyen de gérer la dépendance d’A sur B. La composition du package permet d’itérer B à sa propre cadence, tandis qu’A est libre d’obtenir des mises à jour de B lorsque la planification D autorise, et permet à plusieurs équipes d’itérer et de mettre à jour la solution B sans affecter la solution A (ou d’autres solutions C ou D).
Toutefois, la composition du package est accompagnée de son propre ensemble de défis. Jusqu’à présent, nous avons examiné un exemple simple. La mise à l’échelle de la composition du package jusqu’à la taille d’une base de code volumineuse (comme Windows ou Bing) peut entraîner une série de défis :
Comprendre l’impact des changements cassants dans un composant faible dans la graphe des dépendances devient très difficile.
Les dépendances de diamant peuvent devenir un obstacle important à l’agilité. Dans une dépendance de diamant, les composants B et C dépendent tous deux d’un composant partagé A, tandis que le composant D dépend à la fois de B et C. Lorsque le composant A introduit une nouvelle version avec des modifications cassants, si B met à jour la nouvelle version, mais pas C, D ne peut pas prendre les mises à jour de B sans introduire de conflit de dépendance. Dans cet exemple simple, une conversation avec C peut être nécessaire pour résoudre le conflit. Toutefois, dans un graphique complexe, les diamants peuvent rapidement devenir non résolus.
Lorsque les modifications doivent être appliquées à deux composants composés à l’aide de packages, le cycle d’itération du développeur devient considérablement plus lent. Si le composant A est mis à jour, il nécessite la reconstruction, le repacking et la republier. Par la suite, le composant B doit être mis à jour vers la version récemment publiée pour valider la modification apportée dans le composant A. L’utilisation de la composition source, qui permet la création simultanée du composant A et B, fournira constamment un cycle d’itération plus rapide pour les développeurs.
Que devez-vous utiliser ?
En général, nous avons vu que les grandes équipes sont les plus performantes lorsqu’elles utilisent un mélange de stratégies de composition. Pour déterminer ce qui convient à votre codebase, commencez par mapper les graphe des dépendances de votre produit et commencez à regrouper vos composants en ensembles de composants associés.
Par exemple, vous pouvez avoir une collection de composants constituant votre infrastructure et un autre ensemble de composants formant votre service accessible par l’utilisateur. Ensuite, pour chaque groupe de composants connexes, posez ces questions :
Puis-je anticiper les case activée fréquentes dans les ensembles que j’ai établis pour mes équipes ?
Une seule équipe est-elle responsable de l’ensemble ?
Pour un seul ensemble, existe-t-il une cadence de publication partagée ?
Dans notre expérience, nous avons constaté que l’utilisation de la composition source est la plus efficace pour les projets connexes gérés par une seule équipe ou un groupe d’équipes associées. À l’inverse, la composition binaire s’avère avantageuse pour les logiciels open source, les dépendances externes (composants provenant d’équipes distantes ou isolées) et les composants partagés indépendants.