La meilleure façon de décomposer un code écrasant en morceaux gérables?

13

Je suis constamment submergé par les grands projets, une fois qu'ils atteignent un certain niveau de complexité. Une fois que j'ai atteint un certain point dans un projet, ma progression ralentit et je me retrouve à constamment revenir sur mes pas et à trier toutes sortes de confusion.

J'ai vraiment bien refactoré à cause de ma faiblesse. Et j'essaie toujours de décomposer mes objets en objets plus petits et plus faciles à gérer. Cette faiblesse m'a aussi probablement amené à faire trop attention à bien concevoir les choses.

Je sais que si je peux décomposer mes problèmes en plus petits, je serai en mesure d'accomplir en douceur. Une stratégie qui me vient à l'esprit est le développement piloté par les tests. Que puis-je faire d'autre?

chiot
la source
2
"J'essaie toujours de décomposer mes objets en objets plus petits et plus faciles à gérer" et "Je sais que si je peux décomposer mes problèmes en plus petits, je serai en mesure d'accomplir en douceur" rend votre question un peu rhétorique.
Morgan Herlocker
2
Lisez Refactoring (Fowler) et Design Patterns (GoF) . Cette question demande vraiment "Comment puis-je structurer le code?" et si vous demandez cela, vous avez un long chemin à parcourir; ne comptez pas sur un seul fil de questions / réponses pour vous donner même à mi-chemin.
Aaronaught

Réponses:

13

arrête de penser au code

commencez à penser aux couches, fonctionnalités, modules, services et autres abstractions de niveau supérieur

vous vous sentez dépassé parce que vous pensez à un niveau trop bas

Steven A. Lowe
la source
9

Rendre le complexe simple est facile ; attendez, pensez que c'est l'inverse.

Tout le monde se débat avec cela, il n'y a pas de solution simple qui ait une efficacité extrême.

Comme vous ne l'avez pas mentionné dans vos questions, ma suggestion serait de:

Focus sur la cohésion fonctionnelle via:

Le principe de responsabilité unique stipule que chaque objet doit avoir une responsabilité unique et que cette responsabilité doit être entièrement encapsulée par la classe. Tous ses services devraient être étroitement alignés sur cette responsabilité.

Si vous le recherchez parmi les résultats de la première page sur Google, vous trouverez deux excellentes ressources:

  • " Principe de responsabilité unique " par Robert C. Martin (février / 2002): Ce principe discute de la nécessité de placer les choses qui changent pour différentes raisons dans différentes classes.
  • " Curly's Law: Do One Thing " de Jeff Atwood (mars / 2007): Le principe de responsabilité unique dit qu'une classe devrait avoir une, et une seule, raison de changer.

Qu'est-ce que la cohésion en informatique?

La cohésion est une mesure de la solidité ou de la concentration des responsabilités d'un module unique. Telle qu'appliquée à la programmation orientée objet, si les méthodes qui servent la classe donnée ont tendance à être similaires à bien des égards, alors la classe est réputée avoir une cohésion élevée. Dans un système hautement cohésif, la lisibilité du code et la probabilité de réutilisation sont augmentées, tandis que la complexité est gérée.

La cohésion est diminuée si : - Les fonctionnalités intégrées dans une classe, accessibles via ses méthodes, ont peu en commun. - Les méthodes réalisent de nombreuses activités variées, souvent à l'aide d'ensembles de données à granularité grossière ou sans rapport.

Les inconvénients d'une faible cohésion (ou «faible cohésion») sont: - Une difficulté accrue à comprendre les modules. - Difficulté accrue à maintenir un système, car les changements logiques dans le domaine affectent plusieurs modules et parce que les changements dans un module nécessitent des changements dans les modules associés. - Difficulté accrue à réutiliser un module car la plupart des applications n'auront pas besoin de l'ensemble aléatoire d'opérations fourni par un module.

Si vous avez des questions dites le moi.

bévues
la source
1

Décomposer les fonctionnalités dans le plus petit élément possible. Par exemple, un seul champ sur un formulaire. Choisissez la plus risquée ou la plus prioritaire et avancez comme si c'était une simple correction de bogue, pas un gros projet. Il est vrai que vous vous retrouverez avec un peu de refactoring plus tard, mais au moins vous irez de l'avant.

Bethlakshmi
la source
1

D'après mon expérience, vous avez répondu à votre propre question en commentant TDD. Pour moi, je ressentais souvent la même chose que vous, un succès rapide au début s'est rapidement transformé en embourbement sur des détails mineurs une fois que le système a atteint une certaine taille. J'ai trouvé avec TDD que cela a aidé parce que vous pouviez aborder chaque partie du système en petits morceaux, sachant que le reste du système continuerait ou devrait fonctionner comme vous l'avez laissé. Je pense aussi qu'avec TDD, cela aide à s'assurer que votre système est clairement divisé en plus petits morceaux testables indépendamment.

Paul Hadfield
la source
0

Certaines personnes sont douées pour concevoir des programmes modulaires et facilement compréhensibles, mais la majorité des programmeurs ne disposent pas de cette fonctionnalité, dans une moindre ou plus grande mesure. Je ne connais aucun livre, procédure ou pratique qui puisse transformer l'un des premiers types de programmeurs en deuxième, sauf peut-être pour beaucoup d'expérience. Mais je n'en suis même pas sûr.

L'essentiel est que la plupart des programmeurs auront du mal à s'élever au-dessus du médiocre, quelques-uns réussiront à être OK (c'est là que je me placerais et peut-être 50% des programmeurs professionnels dans (disons) l'industrie de l'IB), et un très une petite minorité sera excellente. Je dois dire que je n'ai jamais rencontré, au cours de ma longue carrière, l'un de ces excellents :-)

Neil Butterworth
la source
2
Je vois d'où tu viens et une partie de moi est d'accord avec toi, mais je ne peux m'empêcher de penser que c'est un peu défaitiste. Oui, il n'y a pas de pilule magique qui transformera un mauvais programmeur en bon, mais grâce à l'expérience, un apprentissage ciblé et une évaluation honnête du travail accompli s'améliorent. La rapidité et l'emplacement du plateau dépendent de l'individu, mais je pense que cela dépend en grande partie de la motivation.
1
+1 @The Mouth of a Cow: d'accord, tout comme Peter Norvig , directeur de la recherche de Google, qui est un "excellent" programmeur: Teach Yourself Programming in Ten Years
bévues le
1
@blunders - un bon article. C'est le sale petit secret que les commerciaux ne veulent pas nous dire (sauf Sega bien sûr). Pratique, pratique, pratique. Cela fonctionne également pour les japonais alljapaneseallthetime.com/blog
J'ai eu un collègue qui a conclu que certains développeurs sont "aveugles à la conception" et ne pouvaient pas concevoir de grands systèmes bien gérés. Si vous êtes aveugle, rien ne vous aidera. Le livre GOF Design Patterns pourrait aider un programmeur qui n'a jamais vu une bonne conception, mais qui a écrit beaucoup de code.
Tim Williscroft
0

Je pense que beaucoup de gens essaient de sur-concevoir des solutions. Ils adoptent l'approche "Adam & Eve" alors qu'une approche légèrement plus pratique simplifierait beaucoup les choses.

Les cours spécialisés ne sont pas mauvais, ils sont la conséquence naturelle d'une conception logicielle saine.

De nombreux programmeurs, à mon avis, ne parviennent pas à comprendre cela et il n'y a pas de livre à ma connaissance qui le dise clairement.

Une autre chose qui aide certainement est TDD, qui vous permet de comprendre "comment" vous utiliserez la classe dans la pratique et peut dans de nombreux cas sauver la journée, car elle montre des problèmes / limitations éventuels tôt dans la journée.

Enfin, une autre chose TRÈS importante que je rechercherais si j'étais vous est les modèles de conception. Les modèles de conception permettent aux gens plus intelligents que vous ou moi de résoudre les problèmes de programmation. L'idée derrière les modèles, devinez quoi?, Est qu'ils ne doivent pas être utilisés comme livres de cuisine, recettes que vous venez de claquer là-bas, mais réfléchis et comprenant d'abord et avant tout votre domaine d'application.

Une utilisation judicieuse du modèle réduira considérablement la quantité de détails que vous devez gérer.

Une bonne bibliothèque de modèles de conception, conçue autour de vos besoins, s'avérera inestimable. Voyons un exemple très simple pour mettre les choses en contexte:

imaginez que vous avez un formulaire où, lorsqu'un bouton est enfoncé, d'autres formulaires doivent se mettre à jour eux-mêmes. Il s'agit d'un schéma typique "d'observateur". Vous avez un sujet et plusieurs observateurs qui s'enregistrent eux-mêmes auprès du sujet. Pourquoi avez-vous besoin d'implémenter une interface? Vous pouvez simplement ajouter les méthodes, ou mieux encore, utiliser une interface pour les observateurs et une liste générique pour le sujet. Maintenant, vous avez le meilleur des deux mondes: l'indépendance pour les observateurs et pas de trucs flous sur le sujet.

J'espère que cela a du sens pour vous!

Andrea

Andrea Raimondi
la source
Soit dit en passant, juste pour être clair: je ne préconise pas des classes sauvages poussant comme des gremlins, plutôt juste un petit plus de sens pratique :)
Andrea Raimondi
0

Le problème de la vitesse de développement et de la lisibilité peut survenir lorsque nous ignorons le besoin d'abstraction. Dans certaines des grandes bases de code sur lesquelles j'ai travaillé, l'ennemi le plus courant était la multitude de classes spécialisées qui ont des fonctionnalités très similaires qui font gonfler le code. Si nous prenons du recul et comprenons les exigences dans leur ensemble et non comme des parties de la demande, alors beaucoup d'abstractions nous viendront à l'esprit.

Quelques étapes simples qui m'ont aidé

  • Utilisez l'analyseur de similitude (comme Simian) pour trouver des blocs de code en double dans la base de code. Beaucoup de code en double signifie moins d'abstraction.
  • Surveillez la taille des classes et des méthodes, de grandes classes et méthodes signifient que peu de services ou de contrôleurs deviennent des dieux.
  • Rendre les tests unitaires / d'intégration obligatoires, vous donne la confiance nécessaire pour refactoriser et agit également comme une spécification.
  • Rétrospective bimensuelle avec l'entreprise pour comprendre si les termes techniques / commerciaux / de domaine qu'ils utilisent sont reflétés dans les noms de classe. Cela aide à comprendre et à obtenir des noms pour des collections de première classe au lieu de les représenter comme de simples ensembles et listes. Certaines abstractions auxquelles nous n'avons jamais pensé feront également surface lorsque nous nous asseyons avec les gens d'affaires.
Vinod R
la source
c'est à peu près ce que je préconise. Ce que je pense, c'est qu'il doit y avoir un équilibre entre abstraction et spécialisation: trop de spécialisation est aussi mauvaise que trop d'abstraction.
Andrea Raimondi