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.