" Philosophie " de l'informatique

Bonjour à  tous !


 

Mes questions concernent les bonnes pratiques et le flair du développeur expérimenté.

 

Premier point, j'ai remarqué que chercher la solution la plus générale était des fois une mauvaise idée et qu'il fallait des fois bidouiller une méthode ad-hoc pour résoudre un problème (gros gain de temps). Au contraire, des fois, perdre du temps à  créer un système de classes général nous fera gagner beaucoup de temps car on pourra le réutiliser partout. 

 

Avez-vous une façon d'aborder ce dilemme " ad-hoc ou général " ?

 

 

Deuxième point : quelle est l'importance du papier ? Vous servez-vous du papier ? En particulier pour certains mécanismes complexes, je ressens le besoin pour documenter mon programme de faire un schéma (et de le scanner et de le mettre dans mon projet xcode). ça peut être en particulier le cas pour le démarrage de l'appli (qui init qui ? quels sont les viewDidLoad et viewDidAppear importants, etc.). Ressentez-vous aussi ce besoin et si oui que faites-vous ?

 

De façon générale, y a-t-il des bons livres (ou post de blogs/vidéos, etc.) qui parlent de ces aspects "philosophiques" du métier ?

 

 

Merci !

Colas

 

«1

Réponses

  • CéroceCéroce Membre, Modérateur
    décembre 2014 modifié #2


     


    Avez-vous une façon d'aborder ce dilemme " ad-hoc ou général " ?



     


    Je crois avoir compris la question, aussi je vais la reformuler avec un exemple. La spec dit "il faut afficher le texte en rouge". À partir de là , il existe deux stratégies:


    - on peut penser que c'est trop bête de se restreindre au rouge, alors qu'en passant un paramètre, on pourrait afficher dans n'importe quelle couleur. On écrit donc son code pour qu'il soit généraliste.


    - ou alors, on se dit qu'on fait ce qui est demandé, point.


     


    Personnellement, j'applique systématiquement la deuxième stratégie pour les raisons suivantes:


    - il est toujours plus difficile de coder que ce qu'on s'imaginait. Par exemple, si on doit passer la couleur en paramètre, on va devoir gérer le cas ou la couleur est nulle, ou qu'en fait ce n'est pas une couleur mais une pattern, etc.


    - je ne suis pas devin, et il est incertain qu'il faille un jour écrire le texte dans une autre couleur. Autant faire le code le plus simple, c'est toujours ça de moins à  maintenir.


    - généraliser le code n'apporte pas de valeur immédiate au client.


    - coder de manière simple n'est jamais du temps perdu: on expérimente comment ça fonctionne réellement, et on cerne beaucoup mieux la problématique.


     


    Cette manière de faire est souvent appelée YAGNI (You Ain't Gonna Need It) ou KISS (Keep It Simple, Stupid). C'est l'approche de base du TDD.


     


    Et ça n'empêche pas de généraliser par la suite. Note que même pour une concevoir une framework, cette stratégie n'est pas si idiote: on se concentre sur les vrais besoins, pas sur quelque chose dont on aura peut-être besoin.


  • CéroceCéroce Membre, Modérateur
    décembre 2014 modifié #3


    Deuxième point : quelle est l'importance du papier ? Vous servez-vous du papier ? En particulier pour certains mécanismes complexes, je ressens le besoin pour documenter mon programme de faire un schéma (et de le scanner et de le mettre dans mon projet xcode). ça peut être en particulier le cas pour le démarrage de l'appli (qui init qui ? quels sont les viewDidLoad et viewDidAppear importants, etc.). Ressentez-vous aussi ce besoin et si oui que faites-vous ?




    J'ai toujours un bout de brouillon pour noter des noms de méthodes, des nombres, des schémas.


    J'ai aussi un cahier pour mettre les schémas au propre et noter des informations importantes ou longues à  retrouver.


    J'ai une liste informatique des tâches à  faire.


    Pour l'architecture, je la dessine plutôt dans un logiciel, ce qui me permet de la garder à  jour (elle est commitée).


  • @Céroce : oui, tu as bien compris ma question ;-) Merci pour avoir partagé ton point de vue. Je m'attendais plus à  des réponses allant dans le sens opposé !


  • @Céroce bis : quel logiciel utilises-tu ? Tu fais les diagramme des classes avec ou plus ?


  • CéroceCéroce Membre, Modérateur
    décembre 2014 modifié #6

    Omnigraffle. C'est le moins mauvais que j'ai trouvé.


    Organigrammes, diagrammes de classe, de séquence et d'états essentiellement.


  • LeChatNoirLeChatNoir Membre, Modérateur
    décembre 2014 modifié #7

    Je vais aller dans le même sens que Céroce mais te donner un autre exemple : celui de mon parcours pro.


     


    J'ai démarré ma carrière dans les services Etudes et Dev. On faisait des logiciels qui répondaient au besoin de l'utilisateur. Et comme j'étais jeune, je m'éclatait à  faire des trucs de dingues, assez complexes mais qui marchaient bien.


     


    Par contre, on se battait tjs avec le service exploitation qui trouvait que nos solutions étaient trop complexes, difficilement exploitables et maintenables.


     


    Plus tard, j'ai eu une opportunité et depuis 7 ans maintenant, je bosse dans le service... exploitation ! :D


    Et aujourd'hui, je comprends le discours qu'on me tenait à  l'époque...


     


    Plus que jamais, je prône maintenant la simplicité.


    Car dépanner des chaines informatiques qu'on ne connait pas à  4h du mat', si tu tombes sur un mec qui est passé par 3 couches d'abstractions, t'as juste envie de lui enfoncé des aiguilles dans le corps :D


     


    [edit] Alors bien sûr, on reste dans le domaine de l'informatique donc on continue à  faire faire aux machines ce qui est répétitif. On fait pas tout manuellement sous prétexte de simplicité :) [/edit]


  • Je garde toujours un cahier et un crayon. Il m'arrive de préférer mettre sur papier un algo complexe, je préfère.

    Je pourrais le faire sur ordinateur, mais entre un éditeur de texte qui va me mettre tout en rouge, un éditeur de code qui va me dire sans cesse que le code est bizarre, je préfère de loin le papier. 

    Ex :




    for (i = 0, i = arrayCount) // Automatiquement en tête, arrayCount est bien [array count], et je fais du ++
     |   reste de ligne
     |   reste de ligne
         Si (blabla == valeurComplexe)
             Blablabla
    blablabla

    J'ai pas le soucis des accolades, je simplifie au maximum, j'ai un truc plus clair, avec mois de symboles/caractères.


     


    Concernant l'autre question :


    Je vais en général au plus simple, par des soucis de temps en général, ou que je n'ai pas envie de passer plus de temps sur un détail qui ne serait sûrement pratiquement jamais changé.

    Je peux cependant, quand les clients sont " répétitifs " et que je les connais mieux, ou alors que je connais potentiellement les futures avancées du projet rajouter des trucs plus " abstraits/haut-niveau ", car je sais que c'est potentiellement une feature qui sera demandé prochainement dans une V2, je pourrais avoir besoin du même type de choses dans un autre projet, etc.

  • AliGatorAliGator Membre, Modérateur
    décembre 2014 modifié #9

    Premier point, j'ai remarqué que chercher la solution la plus générale était des fois une mauvaise idée et qu'il fallait des fois bidouiller une méthode ad-hoc pour résoudre un problème (gros gain de temps). Au contraire, des fois, perdre du temps à  créer un système de classes général nous fera gagner beaucoup de temps car on pourra le réutiliser partout. 
     
    Avez-vous une façon d'aborder ce dilemme " ad-hoc ou général " ?

    Je pratique quasiment systématiquement la philosophie YAGNI & KISS.
     

    Deuxième point : quelle est l'importance du papier ? Vous servez-vous du papier ? En particulier pour certains mécanismes complexes, je ressens le besoin pour documenter mon programme de faire un schéma (et de le scanner et de le mettre dans mon projet xcode). ça peut être en particulier le cas pour le démarrage de l'appli (qui init qui ? quels sont les viewDidLoad et viewDidAppear importants, etc.). Ressentez-vous aussi ce besoin et si oui que faites-vous ?

    Enormément.

    J'ai commencé un nouveau projet il y a 2 semaines. J'ai gribouillé déjà  10 pages de mon cahier avec des schemas dessus. Bon ok, le projet comporte un composant graphique custom, qui fait intervenir des maths dans tous les sens pour dessiner le graphe et le composant selon les valeurs et plein de paramètres, donc c'est du gribouillage de maths. Mais de manière générale, je me sers énormément à  la fois du papier et de tableaux blancs.

    D'ailleurs en tant qu'architecte logiciel, je passe l'essentiel de mon temps à  faire des schemas, diagrammes, sur papier ou sur OmniGraffle, ou des petits points avec un tableau blanc à  faire des schemas dessus... et beaucoup moins de temps à  coder (ce qui n'est plus trop mon boulot, même si je continue encore un peu à  coder en ObjC en bonus. Le papier est mon premier outil, avant le clavier.

  •  


     


    Premier point, j'ai remarqué que chercher la solution la plus générale était des fois une mauvaise idée et qu'il fallait des fois bidouiller une méthode ad-hoc pour résoudre un problème (gros gain de temps). Au contraire, des fois, perdre du temps à  créer un système de classes général nous fera gagner beaucoup de temps car on pourra le réutiliser partout. 
     
    Avez-vous une façon d'aborder ce dilemme " ad-hoc ou général " ?

     


    Moi je généralise. Pour reprendre l'exemple de la couleur de Céroce, je préfère le mettre en paramètre plutôt qu'en dur. Surtout que sur cet exemple précis, ça change très très souvent. Donc je réfléchis souvent à  une conception qui me permette d'anticiper les changements pour gagner du temps sur la maintenance. Avec le peu d'expériences que j'ai (je suis toujours étudiant), j'ai compris que le client changeait souvent d'avis et que donc ça faisait plus de travail. Je préfère aussi faire une fonction que je puisse réutiliser partout, quitte à  perdre du temps dessus que d'aller au plus simple. Pour éviter que des gens s'y perdent aussi, j'essaie de respecter des conventions et de documenté le code avec objective-c doc dans ce cas(je kiff ça perso !!).


     


    Pour le papier, je l'utilise beaucoup. Je trouve ça plus pratique que le clavier.


  • Personnellement je suis entre les 2, je préfère aller vite pour sortir une version rapidement, et ensuite optimiser le code au cas par cas.

  • Le carnet de note et le stylo sont les meilleurs amis du développeur !

  • YAGNI, KISS et TDD


     


    Tableau blanc, plus sympa pour réfléchir à  plusieurs que papier/crayon


    Une fois que c'est propre, documentation dans le Wiki du projet


  • Les acronymes (KISS,etc) sont des graines de dogme.

    J'évite de les employer.


    C'est bien de faire simple, mais pour une appli significative, disons à  partir de 60 h.j, la généralisation doit toujours être en ligne de mire, c'est-à -dire qu'il doit y avoir un refactoring constant pour éliminer du code, creer des interfaces, des classes de base, etc.

    Les tests unitaires peuvent aider dans cette démarche mais ils ne sont pas indispensables.


    La généralisation a un coût pour l'utilisateur car elle impose des contraintes sur l'UI mais elle a aussi un avantage pour lui car ce qui est à  l'intérieur se voit à  l'extérieur.

    C'est-à -dire que s'il y a une cohérence interne, cela va transparaitre dans l'interface utilisateur et donc l'utilisateur va mieux comprendre la logique du logiciel et donc être plus efficace.


    C'est un danger de l'approche agile de perdre cette cohérence invisible en découpant le soft en fonctionnalités developpees sequentiellement.
  • J'vois que beaucoup utilisent le tableau.

    Je ne l'utilise que lorsque la réflexion se fait à  plusieurs.

    Pour de la réflexion perso, je préfère largement faire mes dessins pour la trigo sur ma p'tite feuille de papier.


  • CéroceCéroce Membre, Modérateur

    C'est bien de faire simple, mais pour une appli significative, disons à  partir de 60 h.j, la généralisation doit toujours être en ligne de mire, c'est-à -dire qu'il doit y avoir un refactoring constant pour éliminer du code, creer des interfaces, des classes de base, etc.
    Les tests unitaires peuvent aider dans cette démarche mais ils ne sont pas indispensables.

    Ce que tu appelles "généraliser", mois j'appelle ça "factoriser": quand le code est redondant, bien sûr que je le remanie pour supprimer ces redondances. Mais avant de généraliser il faut déjà  avoir deux cas qui se recoupent. Autrement, on tire des plans sur la comète en se disant qu'il y aura sûrement besoin de généraliser. L'idée est qu'on ne sait pas avec certitude ce qu'il faudra généraliser, alors autant ne pas le faire au départ et attendre que la généralisation devienne nécessaire.

    La généralisation a un coût pour l'utilisateur car elle impose des contraintes sur l'UI mais elle a aussi un avantage pour lui car ce qui est à  l'intérieur se voit à  l'extérieur.
    C'est-à -dire que s'il y a une cohérence interne, cela va transparaitre dans l'interface utilisateur et donc l'utilisateur va mieux comprendre la logique du logiciel et donc être plus efficace.

    Je ne vois pas trop le rapport avec la généralisation. Mais effectivement, l'IHM doit refléter le modèle interne pour que l'utilisateur comprenne les principes et les limites fonctionnelles.

    C'est un danger de l'approche agile de perdre cette cohérence invisible en découpant le soft en fonctionnalités developpees sequentiellement.

    L'approche Agile pense que le design émerge de lui-même, alors que tu penses qu'il doit être planifié. Personnellement, je ne me sens pas capable de planifier correctement la conception, passée une organisation en couche.
  • AliGatorAliGator Membre, Modérateur

    Les acronymes (KISS,etc) sont des graines de dogme.
    J'évite de les employer.

    Et les Design Patterns tu évite aussi de les employer du coup ?

    C'est bien de faire simple, mais pour une appli significative, disons à  partir de 60 h.j, la généralisation doit toujours être en ligne de mire, c'est-à -dire qu'il doit y avoir un refactoring constant pour éliminer du code, creer des interfaces, des classes de base, etc.

    C'est là  que tu as un problème. Si tu généralises trop en avance de phase, tu risques de généraliser pas forcément dans le bon sens, pensant que tu vas avoir besoin de tel ou tel truc et que telle architecture va coller alors qu'en fait finalement vu comment ton app va évoluer, c'est une autre architecture qui va mieux convenir. Et donc tu vas perdre en productivité

    Les tests unitaires peuvent aider dans cette démarche mais ils ne sont pas indispensables.

    Toi, tu cherches à  te faire fouetter !!
    Si tu dis cela c'est que tu n'as pas intégré les pratiques de production pourtant éprouvées sur de nombreux projets industriels ! Les tests unitaires sont indispensables si tu veux garder une qualité correcte de ton projet, éviter les régressions, et limiter les temps passés en Debug ou VABF.

    Ils permettent aussi de faire du TDD et surtout du Red-Green-Refactoring (c'est là  qu'intervient le Refactoring, non pas en mode "généralisation", mais en mode "factorisation du code redondant et mise au propre du code", pas au sens "je refond l'architecture".

    La généralisation a un coût pour l'utilisateur car elle impose des contraintes sur l'UI mais elle a aussi un avantage pour lui car ce qui est à  l'intérieur se voit à  l'extérieur.

    La généralisation n'a aucun rapport avec de quelconques contraintes d'UI. Ton architecture interne d'application ne va pas plus que ça imposer de contraintes UI. Ou alors c'est que tu ne respectes pas le MVC et les Design Patterns usuels.

    C'est-à -dire que s'il y a une cohérence interne, cela va transparaitre dans l'interface utilisateur et donc l'utilisateur va mieux comprendre la logique du logiciel et donc être plus efficace.

    L'ergonomie d'un logiciel n'a pas grand chose à  voir avec son architecture logicielle non plus. L'architecture logicielle permet d'avoir du code modulaire, stable, avec de faibles dépendances et en utilisant des patrons de conception éprouvés (et de limiter les bugs dans une certaine mesure sur ce point). Elle permet de faciliter la compréhension du code et le code flow. Mais elle ne dicte pas ton ergonomie. Je connais des apps qui ont de très bonnes idées ergonomiques, mais avec un code et une archi logicielle qui fait vomir. Et l'inverse.

    C'est un danger de l'approche agile de perdre cette cohérence invisible en découpant le soft en fonctionnalités developpees sequentiellement.

    Un des principes du développement Agile est aussi de penser fonctionnel et ergonomie d'abord, pas technique. L'utilisateur, le technique et savoir si ton code est beau, il n'en a rien à  carrer, ce qu'il veut c'est une application ergonomique, fonctionnelle, et sans bugs. Et pour avoir fait un paquet de projets en tant qu'architecte, tant pour des clients qu'en auto-entrepreneur pour ma propre appli, je sais que le fonctionnel et l'ergonomie d'une application, ça change très souvent, ça évolue. On a beau sortir le papier-crayon dès le début du projet pour imaginer l'application sous toutes ses coutures avant de se plonger dans sa réalisation, même en planifiant l'UX bien à  l'avance, les besoins vont évoluer, les contraintes techniques (charge, nombre d'utilisateurs, ...) vont évoluer... de nouveaux composants ou méthodes du SDK vont apparaà®tre... et tu ne peux pas prévoir ce que sera ton app dans 6 mois ou 1 an.

    Si les principes comme YAGNI existent, c'est parce que les gens qui ont pondu ça ont de l'expérience et savent qu'à  trop vouloir prévoir un truc "parce que ça servira certainement plus tard", c'est pas viable car le "plus tard" s'il arrive, finalement y'a quelques besoins qui ont changé depuis et au final c'est pas comme ça que c'est le mieux d'implémenter, et il faut tout défaire...


    Attention, je ne dis pas de coder comme un cochon et de faire du code spaghetti, TRES loin de là . Il faut faire du code modulaire, avec des modules indépendants, utiliser les Design Patterns adéquats quand ils sont nécessaires (mais pas non plus les sur-utiliser juste pour dire "hé regardez là  j'ai mis en pratique le super design-pattern que j'ai appris l'autre jour", ça sert à  rien) " et faire du TDD aide à  cela au passage. Mais de là  à  dire "ah tiens je vais tout de suite rendre tout paramétrable" (genre la couleur dans l'exemple de Céroce et un peu tout plein d'autres propriétés) alors qu'en fait demain ça sera peut-être autrement, c'est pas spécialement utile.
  • AliGatorAliGator Membre, Modérateur
    Pour rajouter de l'eau au moulin, j'ai 2 exemples concrets pour lesquels je suis bien content d'avoir fait du YAGNI plutôt que d'over-generaliser trop tôt :

    1) CocoaPods. On n'arrête pas de faire du refactoring local, à  force que les demandes de fonctionnalités arrivent, que les besoins changent.
    Par exemple, avant on était tout en librairies statiques, avec l'arrivée de Swift il faut qu'on supporte les Frameworks, mais heureusement qu'on n'a pas implémenté le support des Frameworks dès le début en se disant "tiens on supporte les libs statiques, mais tant qu'à  faire autant généraliser et supporter tous les formats de librairies, ça sera plus modulaire".
    Car depuis, la problématique a changé, maintenant ça fonctionne avec les modules Clang, bref la façon dont on l'implémente aujourd'hui, au moment où on en a besoin (c'est principe même du YAGNI, n'implémenter les choses que quand on en a besoin) est bien différente de la façon dont on l'aurait implémentée si on l'avait implémentée au début de CocoaPods, à  l'époque où il n'y avait pas de modules et où seul OSX supportait les Frameworks.

    2) Un projet actuel sur lequel je bosse, où j'ai un composant custom. Sur mon composant j'ai des contours rouges et des zone remplies d'une couleur orange. Si j'avais dès le début dit "je mets en propriété ces 2 couleurs pour pouvoir les changer" et avait fait tout le nécessaire pour ça, j'aurais fait le boulot pour rien, car hier ils ont finalement choisi de mettre un dégradé au lieu de la couleur unie, et veulent des animations... et du coup j'utilise des CAGradientLayer avec 2 couleurs et pas une seule, et j'ai donc du faire un refactoring en conséquence pour couvrir ce nouveau fonctionnel... refactoring qui ne va pas du tout dans le sens de l'architecture que j'aurais prise si j'avais généralisé ma UIColor dans une @property pour la rendre générique comme toi tu l'aurais fait.
  • Merci pour toutes vos réponses. Ayant toujours codé seul et de mon côté, il me manque cette expérience qui s'acquiert aussi en fréquentant (en travaillant avec) des gens expérimentés... voir comment ils font, leurs petites astuces, etc.


     




     


    Concernant YAGNI, j'imagine que cette philosophie s'applique aussi pour le découpage en classes.


     


    Par exemple, je dois créer une vue. Je me dis : "peut-être que je pourrai couper cette vue (et son VC) en plusieurs vues (et leurs VC) car j'aurai peut-être besoin dans le futur, de réutiliser un de ces composants". YAGNI dirait : non keep it simple et attends d'en avoir réellement besoin pour refactorer.


     


    La prolifération des classes, c'est le mal ?


     


    On m'avait donné un conseil que j'ai trouvé bien, et qui va à  l'encontre du YAGNI. Dès qu'une méthode prend plus de 4 arguments, créer une classe POJO (c'est-à -dire une classe qui a un .m vide, mais qui peut avoir plein de @property) pour factoriser ces arguments. Dans ce cas, je crée une classe POJO dans le même .h et .m que la classe qui l'utilise..... Une manière de cacher la prolifération des classes ?


  • CéroceCéroce Membre, Modérateur

    La prolifération des classes, c'est le mal ?

    Non pas forcément. Une classe doit avoir une responsabilité unique.
    Ensuite, il peut effectivement arriver qu'une classe ait trop peu de lignes de codes; de fait l'infrastructure est inutilement lourde, et on peut décider de la regrouper dans une autre classe.
    (Voir le live " Refactoring " par Martin Fowler).
  • CéroceCéroce Membre, Modérateur
    décembre 2014 modifié #21

    On m'avait donné un conseil que j'ai trouvé bien, et qui va à  l'encontre du YAGNI. Dès qu'une méthode prend plus de 4 arguments, créer une classe POJO (c'est-à -dire une classe qui a un .m vide, mais qui peut avoir plein de @property) pour factoriser ces arguments. Dans ce cas, je crée une classe POJO dans le même .h et .m que la classe qui l'utilise..... Une manière de cacher la prolifération des classes ?

    Ce remaniement s'appelle "Introduce Parameter Object" dans le livre de Fowler.

    Le remaniement du code ne va pas à  l'encontre du YAGNI: on cherche toujours à  conserver la qualité du code interne, mais on ne construit pas l'architecture sur des hypothèses.
  • AliGatorAliGator Membre, Modérateur
    Tout à  fait.

    - Aller à  l'encontre de YAGNI, ça serait de créer la classe POJO dès le début, avec juste 2 @property, pour se dire "comme ça si demain j'ai 3,4, 5, ou 12 arguments, ça sera déjà  prêt".
    - YAGNI dit "pourquoi créer la classe POJO dès le début alors que pour l'instant tu n'as que 2 arguments ? Si vraiment un jour tu commences à  avoir beaucoup + d'arguments, alors là  oui peut-être que la classe POJO se justifiera, et alors à  ce moment là , pas de souci, il sera temps de la créer. Mais tant que tu n'en as pas besoin, c'est pas la peine de le faire trop tôt".


    YAGNI ce n'est pas "ne crée pas trop de classes" ni "ne découpe pas trop ton code". Loin de là , au contraire. Ca ne va pas à  l'encontre d'une bonne architecture modulaire, non.
    YAGNI c'est "ne prévois pas une architecture over-compliquée juste dans l'idée que tu en auras peut-être besoin un jour, plus tard, pour une future fonctionnalité, ou quand on code évoluera". YAGNI c'est "ne code les choses que quand tu en as besoin " tu feras ta classe POJO que quand elle sera utile " pas la peine de mettre en place une architecture "en anticipation d'une future feature qui n'est pas encore spécifiée", il n'est utile d'adopter cette architecture que au moment où tu en as besoin.
  • Dommage qu'on puisse pas "aimer" un sujet en entier !


  • colas_colas_ Membre
    décembre 2014 modifié #24

    Un livre a été cité dans cette discussion : " Refactoring " par Martin Fowler


    Quels autres livres auriez-vous à  conseiller ?


    (ce lien qui n'a rien à  voir est assez marrant)


     


     


    @Ali : tu parles de design patterns. Pourrais-tu faire la liste des principaux design patterns que tu utilises (que tu implémentes) ?


    " MVC


    " Singleton/shared instance/ "Service" comme tu les appelles


    " datasource


    " delegate


     


    Merci ;-)


  • GeoffreyGeoffrey Membre
    décembre 2014 modifié #25

    - Block


    - KVO/Notification


     


    (le lien ne pointe sur rien)


  • FKDEVFKDEV Membre
    décembre 2014 modifié #26


    Ce que tu appelles "généraliser", mois j'appelle ça "factoriser": quand le code est redondant, bien sûr que je le remanie pour supprimer ces redondances. Mais avant de généraliser il faut déjà  avoir deux cas qui se recoupent. Autrement, on tire des plans sur la comète en se disant qu'il y aura sûrement besoin de généraliser. L'idée est qu'on ne sait pas avec certitude ce qu'il faudra généraliser, alors autant ne pas le faire au départ et attendre que la généralisation devienne nécessaire.

     




     


    Ce que tu appelles factoriser, je l'appelle aussi comme ça, c'est faire du rangement. Tout le monde le fait ou devrait le faire.


    Ma règle pour décider de ranger c'est : quand je tape la même chose pour la troisième fois, je me pose la question de factoriser (pas besoin d'acronyme).


     


    Généraliser, c'est autre chose : c'est trouver l'essence des objets.


    Donner plus de potentiel à  une conception. Cela a un prix : réduire la lisibilité du concept et du code.


    Ce n'est cependant pas à  bannir d'emblée même s'il y a un danger à  explorer la généralisation.


     


     


    Exemple : le mariage pour tous.


     


    Nous sommes dans les années 80, je dois créer une app pour gérer les mariages.


    Est-ce que je dois créer une classe "mariage" ou une classe "contrat" ?


    Est ce que je dois créer deux données membres "homme" et "femme" ou deux données membres "citoyen" ?


     


    Je vais d'abord interroger mon client pour bien comprendre ce qu'il entend par mariage.


    Mais je ne vais pas le croire sur parole, je vais le cuisiner car je veux comprendre l'essence du mariage, je vais peut-être le mettre mal à  l'aise en posant des questions qu'il ne s'est jamais posé, mais c'est pas grave.


     


    Le client va peut-être me répondre : "c'est une aberration, on ne marie pas deux hommes ou deux femmes".


    Grâce aux autres questions que je lui ai posées, je pense qu'il a tort car en dehors de toute considération morale et de tout préjugé, j'ai déduit que le mariage est en fait un contrat entre deux parties sur lequel le sexe n'a en fait aucune incidence, si ce n'est sur le formulaire où on doit écrire "monsieur" et "madame".


     


    Sur ce point j'ai confiance dans mon intuition et mon jugement, j'ai recoupé en posant plein de questions.


    Dans ma conception, je vais donc créer deux classes "contrat" et "citoyen", sur le formulaire, je coderai en dur "Mariage", "Monsieur" et "Madame". Je ne vais surtout pas mettre des cases à  cocher "sexe" dont les utilisateurs ne comprendront pas la signification.


    Cela ne prendra pas plus de temps de développement, et peut-être qu'on simplifiera les algorithmes en découplant "sexe" et "personne".


     


    En revanche, j'ai envisagé de généraliser le nombre de personnes à  N dans le contrat au lieu de deux en dur, mais là  je pense que c'est aller trop loin car je n'arrive pas à  mesurer toutes les implications. Mon intuition me dit qu'avec N personnes, je généralise en dehors de l'essence du mariage et que cela va alourdir le code pour rien. 


    Je reste donc sur un contrat entre deux citoyens dont, pour l'instant, je fixerai le sexe en dur à  homme et à  femme dans la construction de l'objet contrat.


     


    Maintenant je peux établir n'importe quel type de contrat entre deux personnes. La contrainte supplémentaire c'est que je dois préciser le type de contrat et le sexe des personnes (car je veux écrire "monsieur" et "madame" dans l'UI).


     


    Si mon client revient me voir dans les années 90 avec une nouvelle idée de contrat appelé le pacs. Pas de soucis. Je peux même lui glisser à  l'oreille : "vous savez on pourrait même créer un mariage entre deux personnes de même sexe si nécessaire", ça ne couterait pas grand chose en développement.


    Je lui ai offert du pouvoir, de la souplesse dans son métier en généralisant à  bonne escient.


     


    Peut-être qu'effectivement, il ne fera jamais de mariage pour tous dans sa cité, dans ce cas, ce n'est pas grave je n'ai rien perdu. 


  • DrakenDraken Membre
    décembre 2014 modifié #27

    T'es au courant que la polygamie est légale dans une cinquantaine de pays, pour la plupart de culture musulmane ?


     


    Cela n'a pas d'importance si ton application est destinée uniquement à  la France, à  l'Europe ou à  l'Occident. Mais dans le contexte actuel de mondialisation des ventes, il faut penser aux différences culturelles.


  • FKDEVFKDEV Membre
    décembre 2014 modifié #28

    Ca reste un contrat entre deux personnes :-).


    C'est juste qu'une personne possède plusieurs contrats.


    Car dans le cas de la polygamie homme -> femmes, les femmes ne sont pas mariées entre elles, n'est-ce pas ?


  • DrakenDraken Membre
    décembre 2014 modifié #29
    Légalement elles sont considérées comme des "soe“urs" entre-elles. C'est un lien légal d'adoption apparaissant au mariage. Faut-il des contrats supplémentaires pour représenter ça ?
  • FKDEVFKDEV Membre
    décembre 2014 modifié #30

    Je suis d'accord avec YAGNI au niveau tactique, c'est du bon sens.


    Pour moi la tentation de faire du code réutilisable n'a jamais été un problème. Je suis trop paresseux pour ça, je fais le minimum nécessaire.


  • Par contre au niveau architecture, ce n'est pas aussi simple. 


     


    Je suis d'accord avec YAGNI : ne prévois pas d'architecture hyper compliquée si tu n'en as pas besoin.


     


    Par contre, il y aurait l'anti-YAGNI qui serait : "mais avant de partir sur une conception restrictive, appelle quand même le client pour savoir s'il prévoit de l'undo/redo, de la synchro ou de la gestion de droits utilisateurs, ou <autre feature pas simple dans ton domaine>."

Connectez-vous ou Inscrivez-vous pour répondre.