Est-il préférable de concevoir de haut en bas ou de bas en haut?


31

Si je comprends bien, la conception descendante consiste à affiner le concept abstrait de haut niveau en petites pièces concrètes et compréhensibles, jusqu'à ce que le plus petit bloc de construction soit défini. D'un autre côté, le bas vers le haut définit les parties de bas niveau, puis construit progressivement des blocs de niveau supérieur jusqu'à ce que tout le système soit formé.

Dans la pratique, il est préférable de combiner les deux méthodes: commence par une spécification de haut niveau pour spécifier pleinement la connaissance du domaine, sa relation et ses contraintes. Une fois le problème bien compris, les plus petits blocs de construction sont créés pour construire le système.

Le processus de:

  • Création d'une spécification d'exigence
  • Créer une spécification de conception (avec des diagrammes)
  • Mettre en place
  • Livrer
  • Répéter (dans le développement itératif, plutôt que de faire un morceau entier dans chaque phase, nous en faisons un peu à plusieurs reprises et nous nous réunissons quotidiennement pour nous adapter aux exigences dynamiques du client)

me semble parfaitement normal (avec des spécifications comme des plans). Il a ses défauts, mais c'est pourquoi nous avons eu un développement itératif: au lieu de passer du temps sur une phase, dit l'analyse des besoins pour étudier tout ce qui est possible dans la connaissance du domaine qui est soumise à des changements (éventuellement quotidiennement), nous faisons un peu d'analyse, un peu de conception, puis l'implémenter.

Une autre façon est que chaque itération est une mode mini-cascade, où l'analyse se fait en quelques jours (ou une semaine). Il en va de même pour le design. Le reste du temps est consacré à la mise en œuvre. Y a-t-il quelque chose d'intrinsèquement mauvais dans l'approche descendante en combinaison avec le développement itératif?

Dans son essai Programming Bottom Up , Paul Graham semble encourager la construction de bas en haut complètement, ou la programmer de bas en haut, mais pas la phase d'analyse des exigences / conception:

Les programmeurs Lisp expérimentés répartissent leurs programmes différemment. En plus de la conception descendante, ils suivent un principe qui pourrait être appelé conception ascendante - changer la langue en fonction du problème.

Pour autant que je sache, ce qu'il voulait dire, c'est que Lisper exécute toujours une conception descendante, mais un programme ascendant, est-ce vrai? Un autre point qu'il a écrit:

Il convient de souligner que la conception ascendante ne signifie pas simplement écrire le même programme dans un ordre différent. Lorsque vous travaillez de bas en haut, vous vous retrouvez généralement avec un programme différent. Au lieu d'un seul programme monolithique, vous obtiendrez un langage plus grand avec des opérateurs plus abstraits et un programme plus petit écrit dedans. Au lieu d'un linteau, vous obtiendrez un arc.

Est-ce à dire que pendant la période d'écriture d'un programme en Lisp, vous vous retrouvez avec un outil générique?


Peut-être que si vous fournissez un lien vers le livre, l'article ou l'article auquel vous faites référence, d'autres pourraient être en mesure de faire une déclaration plus motivée en ce qui concerne votre question. De plus, on ne sait pas exactement sur quoi porte votre question. Demandez-vous des conseils sur certaines spécificités en ce qui concerne une conception que vous souhaitez mettre en œuvre, ou posez-vous des questions sur l'article auquel vous faites référence. Ce serait peut-être plus facile à lire et à répondre si vous le décomposiez en quelques questions posées séparément.
S.Robins

@ S.Robins Pour résumer, j'ai démontré mon approche descendante habituelle pour développer des logiciels. Cependant, certaines personnes préfèrent de bas en haut, et l'un d'eux est Paul Graham, qui est une personne célèbre. Je demande à comprendre comment la conception ascendante aide en général, et en particulier dans Lisp car elle a des fonctionnalités spéciales à encourager (comme l'a suggéré Paul).
Amumu

1
Amumu, j'ai édité l'exemple, car les deux réponses semblent l'avoir de toute façon ignoré. Veuillez essayer de garder vos questions concises et ne posez qu'une seule question par question .
yannis

Réponses:


35

De haut en bas est un excellent moyen de décrire des choses que vous savez ou de reconstruire des choses que vous avez déjà construites.

Le plus gros problème de haut en bas est que, bien souvent, il n'y a tout simplement pas de «sommet». Vous allez changer d'avis sur ce que le système doit faire lors de son développement et lors de son exploration du domaine. Comment peut être votre point de départ quelque chose que vous ne savez pas (c'est-à-dire ce que vous voulez que le système fasse)?

Un top down "local" est une bonne chose ... une certaine réflexion avant le codage est clairement bonne. Mais penser et planifier trop n'est pas, car ce que vous envisagez n'est pas le vrai scénario (à moins que vous n'ayez déjà été là-bas, c'est-à-dire si vous ne construisez pas, mais reconstruisez). Le top-down mondial lors de la construction de nouvelles choses est tout simplement absurde.

La méthode ascendante devrait être (globalement) l'approche, à moins que vous ne connaissiez 100% du problème, que vous ayez juste besoin de coder la solution connue et que vous ne vous souciez pas de rechercher des solutions alternatives possibles.

L'approche Lisp est la méthode ascendante distillée. Non seulement vous construisez de bas en haut, mais vous pouvez également façonner les briques comme vous en avez besoin. Rien n'est figé, la liberté est totale. Bien sûr, la liberté prend des responsabilités et vous pouvez faire des choses horribles en abusant de ce pouvoir.

Mais un code horrible peut être écrit dans n'importe quelle langue. Même dans des langues qui sont conçues comme des cages pour l'esprit, conçues avec l'espoir qu'avec ces langues, même les singes pourraient mettre en place de bons programmes (une idée si fausse à tellement de niveaux que ça fait mal même d'y penser).

Votre exemple concerne un serveur Web. Maintenant, en 2012, c'est un problème bien défini, vous avez des spécifications à suivre. Un serveur Web n'est qu'un problème d'implémentation. Surtout si vous visez à écrire un serveur Web substantiellement identique aux autres gajillions de serveurs Web qui existent, alors rien n'est vraiment flou, à l'exception de quelques détails. Même votre commentaire sur RSA parle toujours d'un problème clairement défini, avec des spécifications formelles.

Avec un problème bien défini, avec des spécifications formelles et des solutions déjà connues, le codage ne fait que se connecter entre les points. De haut en bas est ok pour ça. C'est le paradis du chef de projet.

Dans de nombreux cas, cependant, il n'y a pas d'approche bien connue et éprouvée à utiliser pour relier les points. En fait, il est très souvent difficile de dire même quels sont les points.

Supposons par exemple que l'on vous demande de charger une machine de découpe automatique d'aligner les pièces à découper sur un matériau imprimé qui n'est pas parfaitement conforme au logo répétitif théorique. On vous donne les pièces et les photos du matériel prises par la machine.

Qu'est-ce qu'une règle d'alignement? Tu décides. Qu'est-ce qu'un motif, comment le représenter? Tu décides. Comment aligner les pièces? Tu décides. Les pièces peuvent-elles être "pliées"? Cela dépend, certains non et certains oui, mais bien sûr pas trop. Que faire si le matériau est trop déformé pour qu'une pièce le coupe de manière acceptable? Tu décides. Tous les rouleaux de matériau sont-ils identiques? Bien sûr que non, mais vous ne pouvez pas inciter l'utilisateur à adapter les règles d'alignement pour chaque rouleau ... ce serait impossible. Quelles images voient les caméras? Le matériau, quoi que cela puisse signifier ... il peut être de couleur, il peut être noir sur noir où seul le réflexe de lumière rend le motif évident. Que signifie reconnaître un motif? Tu décides.

Essayez maintenant de concevoir la structure générale d'une solution à ce problème et donnez un devis, en argent et en temps. Je parie que même l'architecture de votre système ... (oui, l'architecture) sera fausse. L'estimation des coûts et du temps sera aléatoire.

Nous l'avons implémenté et maintenant c'est un système qui fonctionne, mais nous avons changé d'avis beaucoup de fois sur la forme même du système. Nous avons ajouté des sous-systèmes entiers qui ne sont même plus accessibles depuis les menus. Nous avons changé de rôle maître / esclave dans les protocoles plus d'une fois. Nous avons probablement maintenant suffisamment de connaissances pour tenter de le reconstruire mieux.

D'autres sociétés ont bien sûr résolu le même problème ... mais à moins que vous ne soyez dans l'une de ces sociétés, votre projet détaillé de haut en bas sera probablement une blague. Nous pouvons le concevoir de haut en bas. Vous ne pouvez pas parce que vous ne l'avez jamais fait auparavant.

Vous pouvez aussi probablement résoudre le même problème. Travailler de bas en haut cependant. Commencer par ce que vous savez, apprendre ce que vous ne savez pas et additionner.

De nouveaux systèmes logiciels complexes se développent, ne sont pas conçus. De temps en temps, quelqu'un commence à concevoir un gros nouveau système logiciel complexe mal spécifié à partir de zéro (notez qu'avec un grand projet de logiciel complexe, il n'y a que trois possibilités: a] la spécification est floue, b] la spécification est erronée et auto-contradictoire ou c] les deux ... et le plus souvent [c] est le cas).

Ce sont les projets typiques de grandes entreprises avec des milliers et des milliers d'heures jetées dans des diapositives PowerPoint et des diagrammes UML seuls. Ils échouent invariablement complètement après avoir brûlé des quantités de ressources embarrassantes ... ou dans certains cas très exceptionnels, ils fournissent finalement un logiciel trop cher qui ne met en œuvre qu'une infime partie des spécifications initiales. Et ce logiciel est toujours profondément détesté par les utilisateurs ... pas le type de logiciel que vous achèteriez, mais le type de logiciel que vous utilisez parce que vous y êtes forcé.

Est-ce à dire que je pense que vous ne devriez penser qu'à coder? Bien sûr que non. Mais à mon avis, la construction devrait commencer par le bas (briques, code concret) et devrait monter ... et votre concentration et votre attention aux détails devraient dans un sens "s'estomper" lorsque vous vous éloignez de ce que vous avez. De haut en bas est souvent présenté comme si vous deviez mettre le même niveau de détail à l'ensemble du système à la fois: il suffit de diviser chaque nœud jusqu'à ce que tout soit évident ... dans les modules de réalité, les sous-systèmes sont "développés" à partir de sous-programmes. Si vous n'avez pas d'expérience dans le problème spécifique, la conception descendante d'un sous-système, d'un module ou d'une bibliothèque sera horrible. Vous pouvez concevoir une bonne bibliothèque une fois que vous savez quelles fonctions mettre, et non l'inverse.

Beaucoup d'idées Lisp deviennent de plus en plus populaires (fonctions de première classe, fermetures, typage dynamique par défaut, ramasse-miettes, métaprogrammation, développement interactif) mais Lisp est toujours aujourd'hui (parmi les langues que je connais) assez unique dans la facilité avec laquelle il est possible de façonner du code pour ce dont vous avez besoin.

Par exemple, les paramètres des mots clés sont déjà présents, mais s'ils n'étaient pas présents, ils pourraient être ajoutés. Je l'ai fait (y compris la vérification des mots clés au moment de la compilation) pour un compilateur Lisp jouet que j'expérimente et il ne prend pas beaucoup de code.

Avec C ++, le plus que vous pouvez obtenir est un groupe d'experts C ++ vous disant que les paramètres des mots clés ne sont pas très utiles, ou une implémentation de modèle incroyablement complexe, cassée et à moitié sauvegardée qui n'est en effet pas si utile. Les classes C ++ sont-elles des objets de première classe? Non et vous ne pouvez rien y faire. Pouvez-vous avoir une introspection à l'exécution ou au moment de la compilation? Non et vous ne pouvez rien y faire.

Cette flexibilité linguistique de Lisp est ce qui le rend idéal pour la construction ascendante. Vous pouvez construire non seulement des sous-routines, mais aussi la syntaxe et la sémantique du langage. Et dans un sens, Lisp lui-même est ascendant.


Oui, ce que je voulais dire, c'était un sommet local. Vous continuez d'affiner l'exigence et de la faire évoluer au fil des itérations. Le point de haut en bas est que nous voulons que la structure du code soit aussi correcte que possible. Refactorisation continue. Par exemple, au début, vous voulez passer une chaîne à une fonction, mais plus tard, vous avez besoin d'une classe entière pour satisfaire les modifications, et le refactoring prend du temps si la fonction est déjà utilisée partout.
Amumu

Reconstruire quelque chose de clairement connu d'une manière clairement connue, puis de haut en bas est correct. Votre navigateur Web en est un exemple. Même en utilisant un langage comme C ++ qui vous oblige à anticiper et à spécifier formellement (en utilisant une syntaxe terrible) tous les types pour les valeurs contenues dans toutes les variables de votre programme est toujours une option viable.
6502

Je ne pense pas que mon exemple soit un moyen clairement connu, car je suppose qu'il est fait par quelqu'un ayant des connaissances de base en communication de données, et le code C ++ est le résultat d'une conception très basique à partir des connaissances du domaine (dans ce cas, la mise en réseau) . C'est un exemple de conception d'évolution. Dans la prochaine itération, le développeur en apprend plus sur les connaissances du domaine, il étend donc sa conception pour s'adapter aux connaissances évoluées (telles que les aspects de sécurité supplémentaires dans chaque couche du serveur Web). Il affine ensuite l'implémentation selon le nouveau design.
Amumu

Le point ici est que la solution réelle dérivée d'un langage indépendant du domaine (comme le langage naturel, le langage mathématique ... dépend du domaine). L'acte de codage est juste un mappage détaillé de la solution générée au code.
Amumu

1
Salut Mr.6502. Après un an, en apprenant plus de choses, je commence à voir ce que tu dis devenir plus vrai. J'ai fait un autre fil: programmers.stackexchange.com/questions/179000/… . Si vous avez le temps, j'espère que vous clarifierez à nouveau ma pensée: D.
Amumu

6

Je ne sais pas comment cette réponse s'appliquerait à Lisp, mais je viens de terminer la lecture des principes, modèles et pratiques agiles , et l'auteur, l' Oncle Bob , préconise fortement l'approche descendante pour C # (également applicable à C ++) avec laquelle j'ai pleinement se mettre d'accord.

Cependant, contrairement à certaines autres réponses qui ont permis de conclure que l'approche descendante signifie que dans la première interaction, vous ne fournissez que des documents et une conception globale, le livre pointe vers une autre méthode: TDD combiné avec une conception évolutive.

L'idée est que vous commencez par le haut et définissez vos niveaux d'abstraction les plus élevés (ou les plus élevés locaux) et dès qu'ils sont définis, vous leur faites un travail utile pour que la fonctionnalité # 1 fonctionne immédiatement. Ensuite, au fur et à mesure que vous ajoutez de plus en plus de fonctionnalités, vous refactorisez votre code et faites évoluer la conception selon vos besoins tout en restant toujours informé des principes SOLID. De cette façon, vous ne vous retrouverez pas avec trop de couches d'abstraction et vous ne vous retrouverez pas avec une conception de bas niveau qui ne correspond pas à l'architecture globale. Si vous n'êtes pas sûr de ce que cela signifie, le livre que j'ai mentionné ci-dessus contient un chapitre entier avec un exemple où les développeurs prennent des concepts et commencent avec des diagrammes UML et des classes de bas niveau, seulement pour réaliser que la moitié de ces classes ne sont pas nécessaires une fois que le codage commence réellement. Essentiellement avec cette approche, le code de bas niveau est naturellement poussé vers le bas à mesure que davantage de détails de haut niveau sont définis dans le projet.

Et enfin, si vous pratiquez SOLID, vous ne devriez pas vous retrouver dans une situation où vous avez défini des abstractions de haut niveau, puis entrer dans les détails et tout à coup trouver qu'il n'y a pas d'OOD ou d'abstractions. Ce n'est pas vraiment la faute de la conception descendante, mais de l'ingénierie paresseuse.

Si vous souhaitez en savoir plus sur XP et le design évolutif, voici une bonne lecture de Martin Fowler, un autre grand auteur: "Is Design Dead?"


Parfait. C'est ce dont je suis en train de parler. Il est également agréable de connaître le principe SOLID et Agile prend en charge l'approche descendante (je pensais qu'avec TDD et XP, les gens sautaient au code dès que possible et évitaient la documentation).
Amumu

@Amumu: J'ai ajouté un lien vers un autre article écrit par Fowler. Vous pouvez en savoir plus sur la différence entre le codage cowboy sans conception / documentation et ce que XP / Agile promeut réellement. Bien que personnellement, je crois fermement que la documentation a de la valeur et que j'ai activement promu mon équipe pour maintenir nos documents de conception, j'ai progressivement changé d'avis. Maintenant, nos "tâches de conception" sont toutes des choses de type tableau blanc / serviette, tandis que les documents réels ne sont mis à jour qu'après la rédaction de l'histoire. Nous avons également réduit ce qui est réellement documenté, de sorte que les documents ne couvrent que les éléments de haut niveau / d'architecture
DXM

3

Pour moi, les remarques les plus importantes de Paul Graham dans son article sont les suivantes:

[...] Les programmeurs Lisp [...] suivent un principe qui pourrait être appelé conception ascendante - changer la langue pour l'adapter au problème. En Lisp, vous n'écrivez pas seulement votre programme vers la langue, vous construisez également la langue vers votre programme.

Ou, comme cela est connu dans les cercles C ++: la conception de bibliothèque est la conception de langage (Bjarne Stroustrup)

L'idée principale de la conception descendante est: d'abord vous planifiez, puis vous codez. Beanow a raison quand il écrit , qu'il y a des problèmes lorsque le code exécutable arrive tard dans le processus. Dans la conception ascendante, vous avez toujours du code et ce code qui peut être testé.

De plus, votre code n'est pas plat. J'entends par là, il a tendance à avoir plus de niveaux d'abstractions plus petites. Dans la conception descendante, les gens se retrouvent souvent avec de grandes abstrations jusqu'à un certain niveau arbitraire et en dessous, aucune abstraction du tout. Le code conçu de bas en haut OTOH contient souvent moins de contrôle de bas niveau et de structures de données car ils sont susceptibles d'être abstraits.


2

Idéalement, l'écriture d'un programme dans n'importe quelle langue, pas seulement Lisp, vous permet d'écrire un ensemble complet d'outils génériques qui peuvent vous accélérer dans votre prochain programme ou améliorer la vitesse de votre programme actuel.

En pratique, le suivi de ces outils peut être difficile. La documentation est pauvre et désorganisée et les gens qui les connaissent partent. Dans la pratique, la réutilisation du code est souvent plus problématique qu'elle n'en vaut la peine. Mais si le code est documenté et organisé correctement et que les programmeurs restent (ou conservent leur propre source de code utile), une grande quantité de travail peut être économisée en récupérant le code de l'entrepôt plutôt qu'en le reconstruisant.

Tout le design doit être descendant, sinon vous ne sauriez pas ce que vous faisiez. Vous construisez un hangar ou une voiture? Vous ne pouvez pas comprendre celui-là avec un design ascendant. Mais si vous prévoyez de construire une roue avant gauche, vous pourriez penser que vous pourriez avoir besoin de plus de roues plus tard, à la fois pour ce projet et pour d'autres. Et si vous construisez une roue réutilisable, vous en aurez quatre pour le prix d'une. (Et 18 pour le semi-remorque que vous construisez ensuite, tout cela gratuitement.)

Notez que contrairement aux vraies voitures et aux vraies roues, si vous avez construit une "roue" logicielle, vous en avez construit un nombre infini.

Plus sur la conception descendante: bien que vous deviez commencer par cela, je me sens obligé de souligner que si vous ne pouvez pas construire une roue, vous devez le savoir avant de travailler beaucoup sur votre voiture. Vous devez donc travailler de bas en haut presque en parallèle avec le travail de haut en bas. De plus, savoir que vous pouvez construire une roue peut suggérer de nombreux projets auxquels vous n'auriez pas pensé auparavant, comme le semi-remorque. Je pense que l'approche descendante doit dominer, mais avec une touche très légère.

Donc, pour continuer à paraphraser Paul Graham, idéalement lorsque vous écrivez un programme, vous vous retrouvez avec beaucoup de pièces réutilisables qui peuvent gagner beaucoup de temps à la fois sur le programme d'origine et dans d'autres. Pour me distancier légèrement de Paul Graham, cela fonctionne dans n'importe quelle langue (bien que certains encouragent le processus plus que d'autres).

L'ennemi de ce processus presque magique sont les programmeurs avec des perspectives à très court terme. Cela peut résulter de défauts de personnalité, mais le plus souvent d'un changement de poste et de responsabilités trop rapide, à l'intérieur et entre les entreprises employeuses.


Wow, j'ai reçu une réponse du 16 février et la boîte de réception n'a rien montré. Je suis d'accord avec vous, il faut toujours avoir un plan, même très léger, puis construire un peu, puis affiner le plan. C'est parfaitement raisonnable. Cependant, je ne semble pas comprendre pourquoi de nombreux développeurs aiment tout planifier dans leur tête tout en écrivant du code. Un temps considérable peut être économisé et ils peuvent se concentrer pour travailler davantage sur le vrai problème plutôt que de refondre en continu l'architecture du code tout au long du processus de mise en œuvre.
Amumu

@Amumu L'une des raisons de la planification lors de l'écriture: certains programmeurs en savent tellement sur ce qu'ils font avec le clavier et la souris sont leur goulot d'étranglement de codage, pas le processus de planification. (Le code réutilisable leur permettrait de faire de nouveaux travaux créatifs qui laisseraient la réflexion redevenir la partie difficile.)
RalphChapin

@Amumu Une autre raison de planifier pendant l'écriture: avec certaines combinaisons langue / programmeur / problème, la langue est la meilleure façon de penser au problème. La langue est le moyen le plus simple de mettre vos pensées sur papier. Je n'ai lu que peu ici et là sur Lisp, mais d'après cela, je pense que c'est particulièrement bon pour cela. (Certaines langues ont d'abord été créées comme un moyen d'exprimer un problème plutôt que de demander à une machine de le résoudre.) S'il est aussi facile de réorganiser votre code que vos pensées, autant le coder. Mais le programmeur, le langage et le problème doivent bien se fondre pour que cela fonctionne.
RalphChapin

C'est fiable. L'idée de la planification est de séparer les connaissances du domaine et les identifications des relations entre les concepts du domaine et le processus de programmation réel. Imaginez que si une classe est utilisée par une douzaine d'autres classes, sans bien planifier la création de l'interface pour communiquer avec d'autres classes, nous pouvons facilement entrer dans l'enfer d'intégration et de refactoring. Dans ce cas, le temps perdu à taper et à restructurer le code dépasse largement le temps passé à s'identifier sur papier.
Amumu

Prenons un exemple: supposons que nous écrivons une application client / serveur. La première chose que nous devons identifier le protocole en définissant les messages d'échange, comment le message est disposé en mémoire (ie en-tête 16 octets, id 4 octets ....). Le diagramme n'est pas égal à la modélisation / planification: abstratt.com/blog/2009/05/03/on-code-being-model . Nous n'avons pas besoin d'utiliser UML ou un diagramme pour modéliser, car UML se concentre à peu près uniquement sur la POO, et le temps passé à taper dans le diagramme de classe UML n'est pas moins que de taper le code réel, sinon plus.
Amumu

1

Qu'est-ce qui ne va pas avec l'approche descendante en combinaison avec le développement itératif?

L'utilisation d'une approche descendante avec le développement itératif ne fournit aucun code de travail dans les premières itérations. Il délivre des documents de conception et ceux sur lesquels le client aura du mal à donner son avis. Des réponses comme «ouais je suppose (c'est trop abstrait pour moi)» ne vous aideront pas à préciser davantage les spécificités du système souhaité par le client.

Au lieu de cela, vous créez uniquement un aperçu général de ce qui est demandé. (Exigences) à utiliser comme ligne directrice générale pour ce qui définit un produit fini et ce qui mérite d'être mis en œuvre en priorité. À partir de là, vous créez des produits fonctionnels pour chaque itération avec lesquels le client peut réellement jouer pour voir si c'était ce qu'il avait en tête. Sinon, ce ne sera pas un problème car il n'a pas été consacré des centaines d'heures à la conception d'un système qui fonctionne différemment de ce que le client demande maintenant.

Paul Graham a-t-il encouragé la construction de bas en haut? Ou simplement le programmer de bas en haut, mais pas la phase d'analyse / conception des exigences?

Je ne parlerai pas pour une autre personne. Je n'ai pas non plus lu son essai. La réponse que je vous donne vient de mon éducation ainsi que de mes expériences.

Cela signifie que pendant la période d'écriture d'un programme en Lisp, vous vous retrouvez avec un outil générique qui peut être utilisé pour écrire des programmes similaires à celui d'origine, n'est-ce pas?

L'utilisation de cette approche signifie que vous vous retrouverez avec des blocs de construction plus abstraits. Tout simplement parce que vous devrez créer des sous-systèmes autonomes qui peuvent être présentés immédiatement, vous ne pouvez pas créer une conception descendante qui est fortement entrelacée et doit être mise en œuvre en même temps. Il améliore la réutilisation, la maintenabilité mais surtout permet une réponse plus flexible au changement.


1
Le gras, à mes yeux, est inutile lorsque vous citez déjà des blocs…
mk12
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.