Classique Vs héritage prototypique

Après avoir lu les deux, j'ai juste la curiosité, comment la communauté de programmation utilise-t-elle cela? Dans quelle situation?

L'héritage basé sur le prototype est plus flexible. Tout objet existant peut devenir une classe à partir de laquelle d'autres objets seront engendrés. Ceci est pratique lorsque vos objets offrent plusieurs ensembles de services et / ou ils subissent une grande partie de la transformation de l'état avant que votre programme n'arrive au point où l'héritage est nécessaire.

Une discussion à large spectre des approches de modélisation est disponible ici: http://steve-yegge.blogspot.com/2008/10/universal-design-pattern.html

Il existe de nombreux problèmes avec l'héritage classique qui n'existent pas avec l'héritage prototypique, tels que:

L'héritage classique

Accouplement serré . L'héritage est le couplage le plus étroit disponible en conception OO. Les classes descendantes ont une connaissance intime de leurs classes d'ancêtres.

Hiérarchies inflexibles (aka duplication par nécessité) . Les hiérarchies monoparentales sont rarement capables de décrire tous les cas d'utilisation possibles. Finalement, toutes les hiérarchies sont «fausses» pour de nouvelles utilisations – un problème qui nécessite une duplication de code.

L'héritage multiple est compliqué . Il est souvent souhaitable d'hériter de plus d'un parent. Ce processus est excessivement complexe et sa mise en œuvre est incompatible avec le processus d'héritage unique, ce qui rend plus difficile à lire et à comprendre.

Architecture fragile . En raison du couplage étroit, il est souvent difficile de refactoriser une classe avec la mauvaise conception car beaucoup de fonctionnalités existantes dépendent de la conception existante.

Le problème Gorilla / Banana . Souvent, il existe des parties du parent que vous ne souhaitez pas hériter. La sous-classement vous permet de remplacer les propriétés du parent, mais cela ne vous permet pas de sélectionner les propriétés que vous souhaitez hériter.

Héritage Prototypique

Pour comprendre comment les héritages prototypiques résolvent ces problèmes, vous devez tout d'abord comprendre qu'il existe deux types différents d'héritage prototypique. JavaScript prend en charge les deux:

Délégation . Si une propriété n'est pas trouvée sur une instance, elle est recherchée sur le prototype de l'instance. Cela vous permet de partager des méthodes dans de nombreux cas, vous donnant gratuitement le modèle de poids mouche .

Concaténation . La possibilité d'ajouter dynamiquement des propriétés à un objet vous permet de copier librement toutes les propriétés d'un objet à l'autre, toutes ensemble ou sélectivement.

Vous pouvez combiner les deux formes d'héritage prototypique pour obtenir un système très flexible de réutilisation de code. Donc flexible en fait, qu'il est banal de mettre en œuvre des héritages classiques avec des prototypes. L'inverse n'est pas vrai.

L'héritage prototype permet la plupart des fonctionnalités importantes que vous trouverez dans les langues classiques. En JavaScript, les fermetures et les fonctions d'usine vous permettent d'implémenter un état privé, et les héritages fonctionnels peuvent être facilement combinés avec des prototypes afin d'ajouter des mixins compatibles avec la vie privée des données.

Quelques avantages de l'héritage prototypique:

Accouplement libre . Une instance n'a jamais besoin de faire une référence directe à une classe parentale ou un prototype. Il est possible de stocker une référence au prototype d'un objet, mais il est mal conseillé, car cela favoriserait un couplage étroit dans la hiérarchie des objets – l'un des plus grands pièges de l'héritage classique.

Hiérarchies plates . C'est trivial avec OO prototypique pour maintenir les hiérarchies hiérarchiques plates – en utilisant la concaténation et la délégation, vous pouvez avoir un seul niveau de délégation d'objet et une seule instance, sans aucune référence aux classes parentales.

Héritage multiple triviale . L'héritage de plusieurs ancêtres est aussi simple que la combinaison de propriétés à partir de prototypes multiples en utilisant la concaténation pour former un nouvel objet ou un nouveau délégué pour un nouvel objet.

Architecture flexible . Puisque vous pouvez hériter sélectivement avec OO prototypique, vous ne devez pas vous soucier du problème du "mauvais design". Une nouvelle classe peut hériter toute combinaison de propriétés de toute combinaison d'objets source. En raison de la facilité de l'aplatissement de la hiérarchie, un changement dans un endroit ne provoque pas nécessairement des ondulations dans une longue chaîne d'objets descendants.

Plus de gorilles . L'héritage sélectif élimine le problème de la banane des gorilles.

Je ne connais aucun avantage que l'héritage classique ait plus de héritage prototypique. Si quelqu'un en a connaissance, veuillez m'expliquer.

Étant donné que Javascript ne prend pas en charge l'héritage "classique" comme le comprend le plus (et vous n'avez pas fait référence à ce que vous avez lu), je suppose que vous voulez dire héritage manipulé comme ceci:

  function base() { var myVar; this.someBaseFunc = function() { } } function derived() { base.call(this); var someOtherVar; this.SomeOtherFunc = function() { } } 

Ma règle générale est la suivante:

  • Si les classes sont complexes et que les instances peu utilisent une approche «classique». Cela permet aux classes d'exposer publiquement uniquement les fonctionnalités qui devraient être rendues publiques.
  • Si la classe est simple et que les instances utilisent beaucoup une approche prototypique. Cela limite les frais généraux de définition et de stockage des références aux fonctions encore et encore lorsque les instances sont créées.