Une autre façon de demander ceci est; pourquoi les programmes ont-ils tendance à être monolithiques?
Je pense à quelque chose comme un package d'animation comme Maya, que les gens utilisent pour différents workflows.
Si les fonctionnalités d'animation et de modélisation étaient scindées dans une application distincte et développées séparément, avec la transmission de fichiers entre elles, ne seraient-elles pas plus faciles à gérer?
If the animation and modelling capabilities were split into their own separate application and developed separately, with files being passed between them, would they not be easier to maintain?
Ne mélangez pas plus facilement les extensions avec plus de facilité pour maintenir un module - en soi - n’est pas exempt de complications ou de conceptions douteuses. Maya peut être l'enfer sur terre à maintenir alors que ses plugins ne le sont pas. Ou vice versa.Réponses:
Oui. En règle générale, deux applications plus petites, moins complexes, sont beaucoup plus faciles à gérer qu'une seule.
Cependant, vous obtenez un nouveau type de bogue lorsque les applications fonctionnent ensemble pour atteindre un objectif. Afin de les faire travailler ensemble, ils doivent échanger des messages et cette orchestration peut mal tourner de différentes manières, même si chaque application peut parfaitement fonctionner. Avoir un million d'applications minuscules a ses propres problèmes particuliers.
Une application monolithique est vraiment l'option par défaut avec laquelle vous vous retrouvez lorsque vous ajoutez de plus en plus de fonctionnalités à une seule application. C'est l'approche la plus simple lorsque vous considérez chaque fonctionnalité séparément. Ce n’est qu’une fois qu’il est devenu grand que vous pouvez regarder le tout et dire "vous savez quoi, cela fonctionnerait mieux si nous séparions X et Y".
la source
Les choses sont rarement aussi simples en réalité.
La scission n’aide en aucun cas à prévenir ces insectes. Il peut parfois être utile de trouver les bogues plus rapidement. Une application composée de petits composants isolés peut autoriser des tests plus individuels (type d'unité) pour ces composants, ce qui peut parfois faciliter l'identification de la cause de certains bogues et leur permettre ainsi de les résoudre plus rapidement.
cependant,
même une application qui semble être monolithique de l'extérieur peut consister en de nombreux composants testables par unité à l'intérieur, de sorte que les tests unitaires ne sont pas nécessairement plus difficiles pour une application monolithique.
Comme Ewan l'a déjà mentionné, l'interaction de plusieurs composants introduit des risques et des bogues supplémentaires. Et le débogage d’un système d’application avec une communication complexe entre processus peut être beaucoup plus difficile que de déboguer une application à processus unique
Cela dépend également de la capacité d'une application plus grande à se scinder en composants, de l'étendue des interfaces entre les composants et de la manière dont ces interfaces sont utilisées.
En bref, il s’agit souvent d’un compromis, et de toutes les réponses «oui» ou «non» sont correctes en général.
Est-ce qu'ils? Regardez autour de vous, il y a des millions d'applications Web dans le monde qui ne me paraissent pas très monolithiques, bien au contraire. Il existe également de nombreux programmes disponibles qui fournissent un modèle de plugin (autant que je sache, le logiciel Maya que vous avez mentionné).
"Une maintenance plus aisée" vient souvent ici du fait que différentes parties d’une application peuvent être développées plus facilement par différentes équipes, ce qui permet une charge de travail mieux répartie, des équipes spécialisées mieux ciblées, etc.
la source
Je vais devoir être en désaccord avec la majorité sur celui-ci. Diviser une application en deux applications distinctes ne rend pas le code plus facile à gérer ou à raisonner.
La séparation du code en deux exécutables modifie simplement la structure physique du code, mais ce n'est pas ce qui est important. Ce qui détermine le degré de complexité d'une application, c'est le degré de couplage des différentes parties qui le composent. Ce n'est pas une propriété physique, mais logique .
Vous pouvez avoir une application monolithique qui distingue clairement les préoccupations et les interfaces simples. Vous pouvez avoir une architecture de microservice qui repose sur les détails de la mise en œuvre d’autres microservices et qui est étroitement associée à tous les autres.
Ce qui est vrai, c’est que le processus de scission d’une application volumineuse en une application plus petite est très utile lorsque vous essayez d’établir des interfaces et des exigences claires pour chaque composant. En langage DDD, cela créerait vos contextes délimités. Toutefois, le fait de créer beaucoup d'applications minuscules ou une application volumineuse ayant la même structure logique relève davantage d'une décision technique.
la source
Plus facile à maintenir une fois que vous avez fini de les séparer, oui. Mais les séparer n'est pas toujours facile. Essayer de diviser un morceau d'un programme dans une bibliothèque réutilisable révèle où les développeurs d' origine a échoué à penser à où les coutures doivent être. Si une partie de l'application pénètre profondément dans une autre partie de l'application, cela peut être difficile à corriger. Découper les coutures vous oblige à définir plus clairement les API internes, ce qui rend finalement la base de code plus facile à gérer. La réutilisabilité et la maintenabilité sont deux produits de coutures bien définies.
la source
Il est important de se rappeler que la corrélation n'est pas une cause.
Construire un grand monolithe puis le diviser en plusieurs petites pièces peut ou non conduire à une bonne conception. (Cela peut améliorer la conception, mais ce n’est pas garanti.)
Mais une bonne conception conduit souvent à la construction d’un système en plusieurs petites pièces plutôt qu’à un grand monolithe. (Un monolithe peut être la meilleure conception, il est juste beaucoup moins susceptible de l'être.)
Pourquoi les petites pièces sont-elles meilleures? Parce qu'ils sont plus faciles à raisonner. Et s'il est facile de raisonner sur l'exactitude, vous obtiendrez probablement un résultat correct.
Pour citer CAR Hoare:
Si tel est le cas, pourquoi quelqu'un construirait-il une solution inutilement compliquée ou monolithique? Hoare fournit la réponse dans la phrase suivante:
Et plus tard, dans la même source (la conférence du prix Turing de 1980):
la source
Ce n'est pas une question avec une réponse par oui ou par non. La question n'est pas seulement la facilité d'entretien, mais aussi l'utilisation efficace des compétences.
Généralement, une application monolithique bien écrite est efficace. La communication entre processus et entre périphériques n'est pas bon marché. Casser un seul processus diminue l'efficacité. Cependant, tout exécuter sur un seul processeur peut surcharger le processeur et ralentir les performances. C'est le problème de base de l'évolutivité. Lorsque le réseau entre en scène, le problème se complique.
Une application monolithique bien écrite qui peut fonctionner efficacement en tant que processus unique sur un serveur unique peut être facile à gérer et à préserver des défauts, mais ne constitue toujours pas une utilisation efficace des compétences en codage et en architecture. La première étape consiste à diviser le processus en bibliothèques qui s'exécutent toujours selon le même processus, mais sont codées indépendamment, en respectant les disciplines de la cohésion et du couplage lâche. Un bon travail à ce niveau améliore la maintenabilité et affecte peu les performances.
L'étape suivante consiste à diviser le monolithe en processus distincts. C'est plus difficile parce que vous entrez dans un territoire difficile. Il est facile d'introduire des erreurs de condition de course. La surcharge de communication augmente et vous devez faire attention aux "interfaces bavardes". Les avantages sont importants car vous cassez une barrière d’évolutivité, mais le potentiel de défauts augmente également. Les applications multi-processus sont plus faciles à gérer au niveau du module, mais le système global est plus compliqué et plus difficile à dépanner. Les correctifs peuvent être diaboliquement compliqués.
Lorsque les processus sont répartis sur des serveurs distincts ou dans une implémentation de style cloud, les problèmes deviennent plus difficiles et les avantages plus importants. L'évolutivité monte en flèche. (Si vous envisagez une implémentation dans le cloud qui ne donne pas une évolutivité, réfléchissez-y bien.) Mais les problèmes qui se posent à ce stade peuvent être incroyablement difficiles à identifier et à envisager.
la source
Non . cela ne facilite pas la maintenance. Si quelque chose, bienvenue à plus de problèmes.
Pourquoi?
Vous avez maintenant deux produits qui nécessitent:
Vous avez maintenant trois marchés de consommation: Modellers, Animators et Modeller Animators.
Cela dit, les bases de code plus petites sont également plus faciles à gérer au niveau de l'application, vous n'obtiendrez tout simplement pas de repas gratuit. C'est le même problème au cœur de Micro-Service / Any-Modular-Architecture. Ce n'est pas une panacée, les difficultés de maintenance au niveau de l'application sont échangées contre des difficultés de maintenance au niveau de l'orchestration. Ces problèmes sont toujours des problèmes, ils ne sont tout simplement plus dans la base de code, ils devront être soit évités, soit résolus.
Si la résolution du problème au niveau de l'orchestration est plus simple qu'à chaque niveau de l'application, il est logique de le scinder en deux bases de code et de traiter les problèmes d'orchestration.
Sinon, ne le faites pas, vous seriez mieux servi en améliorant la modularité interne de l'application elle-même. Insérez des sections de code dans des bibliothèques cohérentes et plus faciles à gérer pour lesquelles l'application agit comme un plugin. Après tout, un monolithe n'est que la couche d'orchestration d'un paysage de bibliothèques.
la source
Il y avait beaucoup de bonnes réponses mais comme il y a presque une scission morte, je jetterai aussi mon chapeau dans le ring.
Dans mon expérience d'ingénieur en logiciel, j'ai trouvé que ce n'était pas un problème simple. Cela dépend vraiment de la taille , de l’ échelle et du but de l’application. Les applications les plus anciennes, en raison de l’inertie nécessaire pour les changer, sont généralement monolithiques car il s’agissait d’une pratique courante pendant longtemps (les Maya seraient admissibles à cette catégorie). Je suppose que vous parlez de nouvelles applications en général.
Dans les applications suffisamment petites qui sont plus ou moins simples concernent la charge supplémentaire nécessaire pour conserver de nombreuses pièces séparées dépasse généralement l'utilité de la séparation. S'il peut être entretenu par une seule personne, il peut probablement être rendu monolithique sans causer trop de problèmes. L'exception à cette règle est lorsque vous avez de nombreuses parties différentes (une interface, une interface, peut-être quelques couches de données entre celles-ci) qui sont commodément séparées (logiquement).
Dans le cas d'applications très importantes, même simples, le fractionnement a du sens, d'après mon expérience. Vous avez l'avantage de réduire un sous-ensemble de la classe de bogues possible en échange d'autres bogues (parfois plus faciles à résoudre). En général, vous pouvez également avoir des équipes de personnes travaillant de manière isolée, ce qui améliore la productivité. De nos jours, de nombreuses applications sont toutefois divisées assez finement, parfois à leur propre détriment. J'ai également fait partie d'équipes où l'application était divisée inutilement en tant de microservices que cela entraînait beaucoup de frais généraux lorsque les choses cessaient de se parler. De plus, le fait de devoir maîtriser toutes les connaissances sur la manière dont chaque partie communique avec les autres devient beaucoup plus difficile à chaque scission successive. Il y a un équilibre, et comme vous pouvez le constater, le moyen de le faire n'est pas très clair,
la source
Pour les applications d’interface utilisateur, il est peu probable que le nombre total de bogues diminue, mais l’équilibre entre la combinaison de bogues et les problèmes causés par la communication sera modifié.
En parlant d’applications / de sites Web d’interface utilisateur, les utilisateurs sont extrêmement non-patients et exigent un temps de réponse court. Cela rend tout retard de communication en bugs. En conséquence, on négociera une diminution potentielle des bogues en raison de la complexité réduite d'un composant unique avec des bogues très graves et de l'exigence de synchronisation d'une communication inter-processus / multi-machine.
Si les unités de données traitées par le programme sont volumineuses (images), tous les retards de traitement croisé seraient plus longs et plus difficiles à éliminer - quelque chose du type "appliquer la transformation à une image de 10 Mo" gagnera instantanément + 20 Mo de disque d'entrée / sortie réseau / réseau à 2 conversion du format en mémoire au format sérialisable et retour. Il n'y a pas grand-chose que vous puissiez faire pour masquer le temps nécessaire à l'utilisateur.
De plus, toute communication, en particulier les E / S de disque, est soumise à des vérifications anti-virus / pare-feu - ceci ajoute inévitablement une couche supplémentaire de bogues difficiles à reproduire et de délais supplémentaires.
La division du "programme" monolithique brille là où les retards de communication ne sont ni critiques ni déjà inévitables
Notez que cela s'applique aux applications de bureau ainsi qu'aux sites Web - la partie du programme destinée aux utilisateurs a tendance à être "monolithique" - tout code d'interaction utilisateur lié à une seule donnée est en général exécuté dans un seul processus (il n'est pas inhabituel de scinder processus sur une base de données comme une page HTML ou une image, mais il est orthogonal à cette question). Même pour les sites les plus basiques avec entrée utilisateur, la logique de validation s'exécute côté client, même si la rendre côté serveur serait plus modulaire et réduirait la complexité / la duplication de code.
la source
Prévenir? Non, pas vraiment.
À savoir tous les bugs que vous ne saviez même pas que vous aviez, que vous avez découverts uniquement lorsque vous avez essayé de scinder tout ce gâchis en parties plus petites. Donc, d’une certaine manière, cela a empêché ces bugs de faire leur apparition dans la production - mais les bugs étaient déjà là.
Les bogues dans les applications monolithiques ont le potentiel de détruire l'ensemble du système et d'empêcher l'utilisateur d'interagir avec votre application. Si vous scindez cette application en composants, la plupart des bogues n'affecteront, par leur conception, que l'un des composants.
Si vous souhaitez que l'expérience utilisateur soit la même, vous devez inclure une nouvelle logique pour la communication de tous ces composants (via les services REST, les appels système, etc.) afin qu'ils puissent interagir de manière transparente à partir du point de vente de l'utilisateur.
Par exemple, votre application monolithique permet aux utilisateurs de créer un modèle et de l’animer sans quitter l’application. Vous divisez l'application en deux composants: la modélisation et l'animation. Vos utilisateurs doivent maintenant exporter le modèle de l'application de modélisation dans un fichier, puis rechercher le fichier, puis l'ouvrir avec l'application d'animation ... Soyons francs: certains utilisateurs ne vont pas comme ça, vous devez donc inclure une nouvelle logique pour le application de modélisation pour exporter le fichier etlancer automatiquement l'application d'animation et lui faire ouvrir le fichier. Et cette nouvelle logique, aussi simple soit-elle, peut comporter un certain nombre de bugs concernant la sérialisation des données, l'accès aux fichiers et les autorisations, les utilisateurs modifiant le chemin d'installation des applications, etc.
Lorsque vous décidez de scinder une application monolithique en composants plus petits, vous le faites (espérons-le) avec beaucoup plus de connaissances et d'expérience sur le système qu'au moment de sa conception, et vous pouvez ainsi appliquer un certain nombre de refactors pour créer le code. plus propre, plus simple, plus efficace, plus résilient, plus sûr. Et cette refactorisation peut, d’une certaine manière, aider à prévenir les bugs. Bien sûr, vous pouvez également appliquer le même refactoring à l'application monolithique pour éviter les mêmes bogues, mais vous ne le faites pas car il est tellement monolithique que vous avez peur de toucher à quelque chose dans l'interface utilisateur et de casser la logique métier ¯ \ _ (ツ) _ / ¯
Donc, je ne dirais pas que vous empêchez les bogues simplement en décomposant une application monolithique en composants plus petits, mais vous aidez en effet à atteindre un point où les bogues peuvent être plus facilement prévenus.
la source