Vous souhaitez participer aux rubriques .NET ? Contactez-moi
Si déboguer est l’art de corriger les bugs, alors programmer est l’art d’en faire
Mon blog, Mes articles, Me suivre sur Twitter
En posant correctement votre problème, on trouve la moitié de la solution
Je l'ai très bien lu. Les arguments Microsoft sont bien présents, comme d'habitude. C'est comme la glorieuse époque ou Microsoft nous expliquait que MVC ca ne servait à rien, qu'ASP.Net faisait aussi bien...Rien de neuf au soleil, à part qu'il y en a toujours pour croire tout ceux que les entreprises, dont le point de vue est toujours basé sur la progression de leur compte en banque et certainement pas sur le bien être général, peuvent dire!
Va parler à un développeur Ruby, qui peut ajouter très facilement n'importe quelle méthode à n'importe quelle classe (possible aussi en C#, mais ce n'est pas un langage interprété comme Ruby). Et c'est extrêmement utile et extrêmement efficace, même sur la classe String.
Et maintenant, qu'on m'explique pourquoi en WPF Microsoft à rendu Sealed les classes Circle, Path, Rectangle (parmis beaucoup d'autres exemples). Très souvent chez Microsoft je vois des classes Sealed qui ne peuvent que me faire penser que le travail n'est pas fini.
Si tu dérives une classe, c'est que tu en as compris le fonctionnement et le code-source, ou alors que tu as besoin de rajouter une fonctionnalité en parallèle. C'est une erreur d'inverser les responsabilités comme Microsoft essaye de le faire avec les habituels arguments que j'ai vu dans ton article.![]()
Je ne vois pas trop en quoi c'est "les arguments Microsoft"... c'est juste des arguments de bon sens. Tu peux penser ce que tu veux, mais l'auteur de l'article est un spécialiste mondialement reconnu, donc désolé si je suis plus convaincu par ses arguments que par les tiens...
Tu parles des méthodes d'extensions en C# je suppose ? Ca n'a rien à voir avec l'héritage, c'est simplement du "syntactic sugar" pour appeler une méthode statique. Ca ne permet absolument pas de modifier le fonctionnement interne de la classe.
D'abord, tu n'as pas forcément accès au code source. Ensuite, pour peu que la classe de base soit un peu complexe, il est difficile de bien comprendre le fonctionnement interne, et en la dérivant tu risques de "briser" les invariants de la classe de base et de l'empêcher de fonctionner correctement.
Dans ce cas, utilise la composition, pas l'héritage... L'héritage est une notion extrêmement puissante, mais c'est aussi celle dont on a le plus tendance à abuser, alors que très souvent ce n'est pas du tout la meilleure approche.
Pas de questions techniques par MP ! Le forum est là pour ça...
Tutoriels : Les nouveautés de C# 6 - Accès aux données avec Dapper - Extraction de données de pages web à l'aide de HTML Agility Pack - La sérialisation XML avec .NET (Aller plus loin) - Les markup extensions en WPF
hum... utiliser la composition ca implique :
1. de faire de la délégation pour toutes les méthodes de l'objet encapsulé
2. de modifier le code existant pour qu'il utilise le nouvel objet composite
C'est un peu lourd, surtout si c'est juste pour ajouter un "intercepteur" sur un appel de méthode.
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
Pour les méthodes d'extension, j'essayais de montrer qu'avoir du code ouvert et modifiable est toujours gagnant, quel que soit la méthode. Évidemment que ca n'a rien à voir avec l'héritage.(d'ailleurs on en revient un peu à l'autre débat sur le jailbreak de l'I..., amusant)
Et ce sera la faute du développeur qui l'aura fait en toute connaissance de cause. La plupart du temps, il gagnera un temps très conséquent parce que ca marchera. J'en sais quelque chose pour avoir été longtemps dans l'Open-Source Java, où je n'ai jamais vu l'utilisation de tels pratique de lock, et pourtant où les architectures logicielles sont souvent plus complexes qu'en DotNet.
La meilleur approche, c'est au développeur utilisateur de la classe de le décider. Parce que justement, jamais personne ne sera capable de définir toutes les utilisations futures d'une classe qu'il développe, mais en même temps réinventer la roue est souvent la moins bonne solution. D'où l'intérêt de l'héritage.
Non vraiment, après plus de 8 ans de J2EE/Java, venir quelques années sur DotNet et découvrir l'utilisation du mot clé Sealed sur une classe qu'on aurait pu surcharger pour régler notre problème en quelques lignes, c'est vraiment rageant et inutile.
Et en 8 ans de Java, tu n'as jamais constaté que Java est bourré de classe de type final ????????????? On nage dans le ridicule là....Pour ton info, il y en a même dans netbeans et dans struts...
Et forcémment, la seule classe sur laquelle repose le projet, tu te rends compte à posteriori que tu ne peux pas la dériver parce que les nazes obteus de chez microsoft ont fait une classe sealed. Sorti de montrer que vous avez des éléments que vous ne maitrisiez pas, ça démontre quoi au juste ?
Que vous avez la vue courte sur vos problèmes de développement ? Que vous ne comprenez pas le paradigme objet ?
Là c'est sans commentaire. Les architectures java plus complexes qu'en .Net.
C'est pour te rassurer ou c'est mesuré au double décimétre ?
Le mythe du développeur Java qui se mure dans la complexité de JBoss dont il doit utiliser 12% au maximum, de l'ORM sur Oracle sans regarder le log SQL (après tout, c'est un ORM), qui utilise du Spring et fout 125 fichiers de paramétrages xml pour faire fonctionner Spring avec JPA et Nhibernate pour finalement faire passer 3 ejb sur un protocole IIOP qui vont être affiché dans un conteneur JSF mélangé à un paradigme MVC qui utilise un conteneur IOC et AspectJ pour fournir une couche d'abstraction et d'extensibilité....et pense faire des choses fabuleuses et qu'il fait de la programmation à haute valeur ajouté alors qu'il vient d'empiler 52 jars et 13 frameworks pour faire du CRUD dans une DB depuis un client léger ? J'espére en plus qu'il y a un intercepteur hibernate qui déclenche un set drools. Sinon, ça manque de créativité.
Et puis, pensez de temps à autres à purger Apache MQ et à brancher la persistence. - 57éme fichier XML, tag "retention_duration_estimated_derivated_averaged_time".
C'est certain que .Net, les architectures distribuées, la persistence, l'Ioc, l'Aop, les serveurs d'application, le messaging, le cache distribué, les langages dynamique...Connait pas !!! Microsoft ne nous a pas expliqué ! Et on attendait un Oracle Prevalence sans interface à implémenter en fait.
Et Oracle est tellement libre et gratuit, JBoss tellement financiérement désintéressé et le code source est tellement clair, WebSphere tellement gratuit, SpringSource ne pratique pas le marketing et la relance commerciale, IBM ne fait jamais payer du conseil hors de prix.
Que j'envie de n'avoir vu ce monde libre où les technologies sont puissantes et gratuites, où le développeur fait des architectures complexes simplement parce qu'il peut dériver une classe quand il veut....
En .Net on fait pas d'objet, parce que Microsoft ne veut pas. Et qu'on fait du .Net parce qu'on ne sait pas développer.
Moi je vais te dire : En tant qu'architecte, même si aujourd'hui je suis plus qu'architecte, bref, je lock mes classes pour éviter que des gens comme toi ne les dérivent.
Je suppose que dans la même logique, jamais d'abstract : A quoi peut servir un objet que tu ne peux qu'implémenter ? Qui est le même raisonnement à l'opposé en fait...
Moi je vais juste donner un avis sur le fameux seal/final finalement après réflexion, parce que franchement, je crois que ça vaut la peine de lever le nez du guidon.
Quelques Généralités
Je suppose qu'on peut dire pour que tout le monde soit au même niveau, que nous avons deux types d'objets généralements utilisés : les classes "concrêtes" et les classes "abstraites".
Les secondes sont souvents utilisées pour généraliser des comportements connus et dont les implémentations ne modifient pas le comportement ou induise une surcharge fiable.
Les premiéres sont des implémentations concrêtes d'objets d'usages divers qui peuvent ou pas hériter / dériver d'une classe abstraite/concrête
Ce principe permet donc :
- De généraliser un comportement ou des propriétés (concision et non redondance des informations)
- De créer des prototypes d'objets
- De gérer des construction d'objet cohérentes et permettant d'instancier des objets ayant une utilité concrête et implémentant correctement les propriétés héritées.
Bref, c'est le bonheur originel de faire de la poo !
l'Ouverture-fermeture, l'objet du délit
L'héritage se fait entre objets. Et la récursivité finalement qu'engendre l'héritage est une des failles logicielle des plus courantes. Elle est cependant rarement rencontrée dans les architecture objet car l'objet est souvent et malheureusement un dto qui n'a pas de vrais fonctionnalités métier. En revanche, elle est plus courante dans un framework qui va délivrer de la méthode et du service.
C'est à dire que l'objet A hérite de B, et l'objet C hérite de B, et l'objet D hérite de A, créant ainsi une hétérogénéité désastreuse.
Au milieu de ce maelstrom objet potentiel; les risques principaux sont :
- La prolifération d'objets anémiques / par design les développeurs vont systèmatiquement dériver au gré de leurs besoins sans chercher une réponse concrête; il s'agit d'un risque de perte de cohérence
- La baisse de qualité du design, redondance, code inutile, "bricolage".
- La testabilité des objets est mise en péril. Autoriser un développeur à dériver d'une classe signifie que toutes les logiques utilisant ce type pouvant être par exemple un traitement générique vont fonctionner avec cet objet dérivé.
Mais le principal risque simplement d'avoir des objets qui viole le principe de substitution. C'est à dire de faire façe à une dérivée dont la complexité dépasse l'origine et devient dès lors l'objet principal. (ou du moins la préoccupation principale)
Pour cela, l'abstract permet de définir un objet fondamental non exploitable, et le seal permet de définir un point final du modéle objet exploitable et non dérivable. Couplé avec une programmation par interface, il s'agit d'un modéle recommandable aux architectes qui souhaitent mettre en oeuvre une architecture permettant :
- D'avoir des éléments testables, atomiques et utiles
- D'offrir aux développeurs une assise fonctionnelle claire avec des responsabilités assumées
- De péreniser un modéle objet en délimitant son périmêtre de responsabilité.
Nous avons donc les moyens de garantir une modélisation ouverte - fermée, et donc de garantir la qualité de la modélisation objet.
Vers la responsabilité de l'objet - cas de la monnaie
Très simplement, prenons l'exemple d'un cas :
Le type money.
Cas séculaire de l'informatique, qui est utilisé intensivement par les établissements financiers, le type money n'est jamais implémenté dans les frameworks. D'ailleurs il est pris en exemple par Fowler dans son ouvrage.
Le type money quand il est implémenté permet de gérer :
- Un montant par son expression numérique
- Son association à une devise qui va définir :
- La règle de décimalisation des montants
- La règle de conversion (Comment convertir 100€ en USD)
- La règle d'affichage (Comment afficher 100 €, 100 USD....)
- La troncature à appliquer
Ce type va être central dans une application financiére, si il n'y est pas, cherchez alors la gestion de l'epsilon et tous les développements liés à la décimalisation des montants, et vous comprendrez l'utilité de l'avoir en tant qu'objet 'clean'.
Il est important de comprendre ici un des vrais enjeux de la programmation objet :
En dehors d'un raisonnement académique et technique sur les principes objets, la poo ne permet pas en elle même de définir la criticité des objets. La criticité est une appréciation "molle", libre au développeur. Le développeur choisi son type, son keyword, ses propriétés.
Or, la cohérence, la testabilité, et surtout l'utilité d'un objet et du modéle objet sont la conséquence directe de la prise en compte par le concepteur de la criticité des éléments, en dehors de toute notion technique.
Pour imager cela, prenons un meuble, qui pour nous est un type abstrait.
Est-il technique de dire que sur tous les meuble peuvent être posés un ou des verres ou chaque meuble est éventuellement capable d'en recevoir un (fonction de sa taille) ou capable d'en recevoir plusieurs, ou capable d'en recevoir zéro (fonction d'une destination ou d'une taille) ?
C'est important de rappeller qu'ici, ce qui importe c'est d'utiliser les outils de la POO pour apporter une réponse non pas ouverte à l'infinie par dogme technologique ou académique, mais fiable et cohérente et permettant de continuer à créer de nouveaux meubles en se posant les bonnes questions.
C'est là qu'est la mauvaise solution : considérer que tout objet doit pouvoir être dérivé. C'est un raccourci qui évite souvent de se poser la question de la nature de l'objet et de son rôle et de faire une implémentation à l'arrache : si ça ne va pas, on pourra dériver.
Un bon objet est un objet :
- Dont la responsabilité est connue
- Dont le rôle est unique
- Dont l'utilité est connue
- Dont le comportement est prédictible
Même si je pense que cette liste est longue, il faut ici comprendre que l'ouverture extrême est un mal qui ronge beaucoup d'application. Les frameworks deviennent anémiques, et la composition et l'héritage viennent souvent finir la maturation des mycoses applicatives.(Et souvent aussi la prise d'antidépresseur du DBA qui pointe son nez avec les traces SQL dues à l'utilisation d'un ORM sur ces objets mal foutus qui font 475 lignes)
Pourquoi fermer une classe?
Pour une raison simple : une fois notre type Money testé, implémenté et fonctionnel, semble-t-il logique que de part sa nature fonctionnelle / métier critique, bien qu'il soit trivial en complexité, soit dérivé pour répondre à des cas qui lui sont inconnus ?
Pour poser la question autrement : Est-il sain de croire que la fragmentation des comportements métier des objets critiques soit autorisée ?
La réponse est : Non. C'est un risque. Et avant d'être un risque technique, c'est un risque financier. On ne peut laisser la responsabilité à un développeur d'une organisation quelconque la possibilité de modifier et de généraliser potentiellement cette modification d'un aspect critique.
Sans rentrer dans l'historique de la programmation par contrat et de liskov, disons qu'il s'agit d'un anti-patron et qui plus est d'une fausse bonne-idée ou une fausse conception de la programmation objet.
Donc, nous devons faire le nécessaire pour éviter la dérive (tant celle de la machine à café que celle de l'orgie de dérivées niémes)
Comment mettre en oeuvre cela ?
Le final ou le seal, permet de rendre une classe non héritable. Par principe et par choix de design, la classe scellée ne permet pas de créer un objet héritant de celle-ci.
La bonne pratique revient donc à bloquer par l'utilisation d'une classe fermée, ou sealed en C#. Notons que Java dispose d'une mécanique similaire et plus rigoriste qui est final, s'appliquant aux objets, propriétés et méthodes. Java et C# permettent d'explicitement interdire la surcharge d'une méthode.
L'utilisation de cet attribut permet de rendre les classes exposées non dérivables.C'est à dire que votre produit va exposer un périmétre connu de fonctionnalités (qui ne veut pas dire restreint d'ailleurs, ni rigide) et qu'une évolution peut intervenir mais nécessite une conception.
L'objet ne doit pas être perçu comme un besoin vital de pourrir la vie de l'utilisateur, mais comme une notion lui permettant de comprendre que ce qu'il souhaite en faire en utilisant l'héritage n'est pas possible parce qu'il y a peut être un risque conceptuel à prendre en considération. C'est un garde fou logique.
Cette mise en oeuvre est souvent propre aux équipes d'architecture ou de conception qui vont pouvoir ainsi contrôler les éléments mis à disposition des équipes d'ingenierie qui vont pouvoir ainsi travailler en terrain connu et participer à une chaine de progression logicielle sainen traitant l'évolution comme une amélioration et non comme une digression objet non maitrisée.
Et à l'avenir rien n'empêche de débloquer l'objet si il est certain que la dérivation n'est pas source de problèmes.
Toute cette tartine de texte pour nous expliquer que tu interdis l'héritage parce que tu n'as pas confiance en ce que pourraient faire des développeurs qui souhaiteraient délibérément faire un héritage ?
De mon point de vue c'est soit de la paranoïa, soit un complexe de supériorité.
Le seul cas pratique que je vois pour mettre "final/sealed", c'est que le code ou l'archi viole tellement les règles de bonnes conduites qu'une éventuelle surcharge/dérivation ruinerait à coup sûr le fonctionnement.![]()
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
Montre-moi un seul DP ou algo qui fonctionne si-et-seulement si une classe n'est pas sealed.
Ca marche aussi, tu sais.
Parfois dériver une classe n'a aucun sens : String, par exemple.
Sealed/final apporte une sémantique supplémentaire à notre attirail. Cracher dessus parce qu'on aurait aimé dériver une classe et ajouter ou overrider des méthodes... Euh... Ouais. La composition, tu connais pas ?
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
Une bonne partie des DP utilisent l'héritage de classe, oui. Mais rien ne t'empêche de reproduire ces DP avec de la composition.
Sinon, ton troll sur System.Object... De la part d'un rédacteur/modo, je trouve ça assez minable. Sans chercher à te vexer ou te dénigrer, hein. J'essaie juste de .... T'éviter de partir dans des dérives inutiles.
Il y a un excellent papier, je ne sais plus où, écrit par l'un des concepteurs de Java... Ou bien s'agit-il d'une interview ? Je ne sais plus. Peu importe. Il explique notamment que s'il devait changer une seule chose dans Java, c'est l'héritage de classe, qu'il supprimerait simplement et totalement. Qu'il laisserait juste l'implémentation d'interfaces.
Parce que tu penses uniquement technique et pas métier. L'utilité des mots-clés n'est pas technique, une utilisation purement technique n'a pas de sens.
Le but de concevoir une application, ce n'est pas de pondre une infra bouse métier qui est une super conception en hommage au design pattern et à l'esprit "libre". C'est de faire une application fiable et robuste. L'héritage n'est pas la meilleure source de fiabilité. Et encore, la casse est limitée parce qu'il n'y a pas d'héritage multiple en c# et en java.
Donc tu es surtout un architecte technique qui utilises des principes techniques et donc finalement, ce que tu devrais dire c'est que tu n'as pas besoin de l'objet, tu as besoin du relationnel. L'ouverture et la fermeture sont les fondements de la POO, et le seal doit exister autant que l'abstract, sinon c'est une dérive à l'infinie qui pourrait aller jusqu'à polluer les frameworks.
C'est comme des développeurs .Net qui vont passer 2 semaines à implémenter un design pattern observer : ça ne sert à rien.
Moi je suis un architecte qui milite pour du code fiable, utile et maintenable. Donc une utilisation stricte et encadrée de l'héritage et du polymorphisme.
Sur un site web naruto, ou une application de gestion de pme; ca n'a pas d'utilité, c'est même contre productif. Sur une application critique de grande taille, il faut se prémunir des facteurs humains :
- Le turn over
- Le temps
- Les changements
- Les variations de compétence
Excuses-moi quand je lis ton raisonnement c'est comme si une application n'existait que du fait de son architecture technique et de sa compliance au rigorisme de la communauté du libre. Alors qu'elle n'existe que du fait des gens qui la créent et l'entretiennent et la technique est secondaire et reléve du choix. Il faut alors l'utiliser comme un levier et pas comme un dogme révolutionnaire.
Et en même temps, on a pas besoin d'être d'accord, ça n'apportera rien à personne.
On peut toujours le faire, bien sur. Ou alors passer uniquement par des implémentations d'interfaces (ce qui ressemble grandement a de l'héritage). Mais ca implique que l'architecture d'origine soit conçue spécialement pour permettre l'extensibilité.
A la rigueur dans le cas où l'on concoit une librairie ou un framework, on peut espérer que l'archi soit bien conçue et qu'il soit possible d'étendre les fonctionnalités sans recourir à l'héritage+surcharge. Donc pour les classes standard de .net/java on peut supposer que le "sealed" n'est pas bloquant. De là à dire qu'il est nécessaire... hum...
Pour le cas d'une application, qui n'est pas spécialement concue pour être extensible, le "sealed" c'est plutot un moyen de "protection" comme le dit B.AF. Ou alors, c'est pour interdire clairement l'extensibilité, et c'est un peu dommage.
OK. J'ai pris un cas extrême, je te l'accorde. J'aurais du dire :Sinon, ton troll sur System.Object... De la part d'un rédacteur/modo, je trouve ça assez minable. Sans chercher à te vexer ou te dénigrer, hein. J'essaie juste de .... T'éviter de partir dans des dérives inutiles.
- Tu prends n'importe quel code qui fonctionne, tu retires les "sealed", il marche pareil.
- Tu prends n'importe quel code qui fonctionne, tu ajoutes des "sealed", ... et bien ca compilera peut-être pas.
Si tu fais une librairie et qu'entre la v1 et la v2 tu ajoutes des "sealed" par endroit, les utilisateurs de ta librairie risquent de ne pas pouvoir recompiler les applis. C'est méchant. Ou alors, à l'inverser, il faut commencer par tout mettre en "sealed" et ouvrir au fur et a mesure des versions.
Oui, je suis d'accord avec ça. Mais remplacer totalement l'héritage par un autre mécanisme équivalent et interdire l'héritage de temps en temps, ce n'est pas la meme chose.Il y a un excellent papier, je ne sais plus où, écrit par l'un des concepteurs de Java... Ou bien s'agit-il d'une interview ? Je ne sais plus. Peu importe. Il explique notamment que s'il devait changer une seule chose dans Java, c'est l'héritage de classe, qu'il supprimerait simplement et totalement. Qu'il laisserait juste l'implémentation d'interfaces.
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
On peut dire la même chose de public/private, non ?
Après tout, si on met des public partout, ça fonctionne toujours... J'irais pas jusqu'à dire que ça fontionne "pareil", par contre.
Et si tu rends tout private... Bah, ça marche plus.
C'est le même genre de bétise, hein. Sealed n'est pas nécessaire ? Ok, admettons : au même titre que private, donc.
Oui, mais là tu changes surtout les signatures de ce que tu exposes aux utilisateurs de ton code, donc, forcément, ils sont un peu obligés de revoir leur code.
C'est pas la même chose, non, mais ça serait peut-être mieux de remplacer totalement l'héritage de classe par un autre mécanisme.
De nous deux, c'est toi qui semble attaché a ce mot-clé technique qui est "sealed". Perso, je vis très bien sans ce concept (qui d'ailleurs n'est pas très modélisable)
En tant qu'archi, je travaille essentiellement sur des concepts, des abstractions, des généralisations/spécialisation, des responsabilités et des mécanismes (généralement dans cet ordre).
Nulle part la dedans n'intervient de la "technique" liée à un langage plutot qu'un autre. Bien sur, je prends en compte les possibilités et limitations techniques des langages (= contraintes), mais je ne les utilise pas comme fondations de l'architecture.
Je laisse la liberté aux developpeurs - qui sont bien plus compétents que moi dans l'utilisation de leur langages respectifs - d'utiliser les mots-clés, les structures et les snippets qui vont bien. S'ils veulent utiliser "sealed" sur une classe parce que c'est "mieux", je les laisse faire. Mais je ne vais certainement pas leur imposer cela, sous pretexte que l'architecture en a absolument besoin (d'ailleurs je n'ai pas d'exemple où c'est absolument nécessaire).
Oui, il faut se prémunir des facteurs humains. Seulement pour moi ce n'est pas une problématique d'architecture. Faut voir cela avec le chef de projet, le scrum-master, les spécificateurs, le controle-qualité...
Le mot-clé "sealed" a sans doutes tout un tas de bonnes raisons pour exister, mais pour moi il n'y en a aucune en rapport avec l'architecture. Et c'est ce qui m'a interloqué dans ton 1er post.
Moi je me cantonne a faire de l'architecture. Visiblement tes responsabilités sont plus étendues que les miennes. C'est sans doute la raison de notre désaccord.![]()
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
"private" est également une mesure de protection... mais c'est pour un concept OO qui est l'encapsulation.
Je ne pense pas que "sealed" protège un concept OO, ou alors je ne vois pas lequel.
Hum... je ne connais pas assez le C# pour le dire. En quoi ca change les signatures d'ajouter sealed sur une classe ?Oui, mais là tu changes surtout les signatures de ce que tu exposes aux utilisateurs de ton code, donc, forcément, ils sont un peu obligés de revoir leur code.
Oui, je suis d'accord. Les cas où j'ai réellement besoin de faire de l'héritage (au sens du liskov) sont très rares.C'est pas la même chose, non, mais ça serait peut-être mieux de remplacer totalement l'héritage de classe par un autre mécanisme.
Et il est vrai que beaucoup de devs utilisent l'héritage comme un moyen de factoriser/réutiliser du code, ce qui peut vite devenir ingérable. Dans ce cas, le "sealed" peut être un bon moyen de protection. Mais bon, vu que ce sont les devs eux-meme qui doivent mettre cette protection...
En quoi cette classe doit-elle etre "sealed" ? (question sérieuse)
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
Remarque, une utilisation du seal théorique est l'interface : bloquer la fonctionnalité par l'imposition d'un contrat.
Là encore, on peut aussi poser un verrou car il n'est pas nécessairement souhaitable que l'on puisse modifier le contrat exposé.
En poo le seal correspond au principe de fermeture, et l'abstract au principe d'ouverture. C'est une mise en pratique du design par responsabilité.
Pour le String réponse sérieuse : pourquoi ne devrait-elle pas l'être ?
Parce que toi tu vas juger qu'il est nécessaire de pouvoir dériver tout objet "au cas où c'est nécessaire", et nous te répondrons qu'il n'est pas nécessaire d'envisager la possiblité qu'on objet puisse être dérivé de façon systèmatique.
Les deux réponses ont du sens. L'une est plus adaptée à répondre à des problèmatiques rencontrées en développement itératif, l'autre est plus adaptée à une logique de développement par la qualité de conception.
Partager