Ereditarietà prototipale classica vs

Dopo aver letto di entrambi, ho solo curiosità, come la comunità di programmazione usa questo? In quale situazione quale?

L’ereditarietà basata su prototipi è più flessibile. Qualsiasi object esistente può diventare una class da cui verranno generati oggetti aggiuntivi. Questo è utile quando i tuoi oggetti offrono diversi set di servizi e / o subiscono molte trasformazioni di stato prima che il tuo programma arrivi nel punto in cui è necessaria l’ereditarietà.

Una discussione ad ampio spettro sugli approcci di modellazione è disponibile qui: http://steve-yegge.blogspot.com/2008/10/universal-design-pattern.html

Ci sono molti problemi con l’ereditarietà classica che non esistono con l’ereditarietà prototipale, come ad esempio:

Eredità classica

Accoppiamento stretto L’ereditarietà è l’accoppiamento più stretto disponibile nel design OO. Le classi discendenti hanno una conoscenza intima delle loro classi di antenati.

Gerarchie inflessibili (alias duplicazione per necessità) . Le gerarchie monoparentali sono raramente in grado di descrivere tutti i possibili casi d’uso. Alla fine, tutte le gerarchie sono “sbagliate” per nuovi usi – un problema che richiede la duplicazione del codice.

L’ereditarietà multipla è complicata . È spesso desiderabile ereditare da più di un genitore. Tale processo è straordinariamente complesso e la sua implementazione è incoerente con il processo di ereditarietà singola, che rende più difficile la lettura e la comprensione.

Fragile architettura A causa dell’accoppiamento stretto, è spesso difficile refactoring di una class con il design “sbagliato”, perché molte funzionalità esistenti dipendono dal design esistente.

Il problema Gorilla / Banana . Spesso ci sono parti del genitore che non vuoi ereditare. La sottoclass consente di sovrascrivere le proprietà dal padre, ma non consente di selezionare le proprietà che si desidera ereditare.

Eredità prototipale

Per comprendere in che modo l’ereditarietà prototipale risolve questi problemi, è necessario innanzitutto comprendere che esistono due tipi diversi di eredità prototipale. JavaScript supporta entrambi:

Delegazione Se una proprietà non viene trovata su un’istanza, viene cercata sul prototipo dell’istanza. Ciò ti consente di condividere i metodi tra molte istanze, dandoti gratuitamente lo schema del peso mosca .

Concatenazione La possibilità di aggiungere dynamicmente le proprietà a un object consente di copiare liberamente tutte le proprietà da un object a un altro, tutte insieme o in modo selettivo.

È ansible combinare entrambe le forms di eredità prototipale per ottenere un sistema di riutilizzo del codice molto flessibile. È così flessibile, infatti, che è banale implementare l’ereditarietà classica con i prototipi. Il contrario non è vero.

L’ereditarietà prototipale consente la maggior parte delle funzionalità importanti che troverai nelle lingue classiche. In JavaScript, le chiusure e le funzioni di fabbrica consentono di implementare lo stato privato e l’ereditarietà funzionale può essere facilmente combinata con i prototipi per aggiungere mixin che supportano anche la privacy dei dati.

Alcuni vantaggi dell’ereditarietà prototipale:

Accoppiamento lento Un’istanza non ha mai bisogno di fare un riferimento diretto a una class genitore o prototipo. È ansible memorizzare un riferimento al prototipo di un object, ma è sconsigliato, perché ciò favorirebbe un accoppiamento stretto nella gerarchia degli oggetti – una delle più grandi insidie ​​dell’ereditarietà classica.

Gerarchie piatte . È banale con OO prototipale per mantenere piatte le gerarchie di ereditarietà – utilizzando la concatenazione e la delega, è ansible avere un unico livello di delega degli oggetti e una singola istanza, senza riferimenti alle classi parent.

Trivial multipla ereditarietà . Ereditare da più antenati è facile come combinare proprietà da più prototipi usando la concatenazione per formare un nuovo object o un nuovo delegato per un nuovo object.

Architettura flessibile Dal momento che puoi ereditare selettivamente con OO prototipale, non devi preoccuparti del problema del “design sbagliato”. Una nuova class può ereditare qualsiasi combinazione di proprietà da qualsiasi combinazione di oggetti sorgente. A causa della facilità di appiattimento della gerarchia, un cambiamento in un punto non causa necessariamente increspature lungo una lunga catena di oggetti discendenti.

Niente più gorilla . L’ereditarietà selettiva elimina il problema della banana dei gorilla.

Non sono a conoscenza di alcun vantaggio che l’ereditarietà classica abbia sull’eredità prototipale. Se qualcuno ne è a conoscenza, per favore illuminami.

Dal momento che Javascript non supporta l’ereditarietà “Classica” come la maggior parte capirebbe (e non hai dato alcun riferimento a ciò che hai letto), suppongo che tu intenda l’ereditarietà gestita in questo modo:

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

La mia regola generale è:

  • Se le Classi sono complesse e le istanze sono poche usano un approccio “classico”. Ciò consente alle classi di esporre pubblicamente solo le funzioni che dovrebbero essere rese pubbliche.
  • Se la class è semplice e le istanze sono molte usano un approccio prototipale. Ciò limita il sovraccarico di definire e memorizzare i riferimenti alle funzioni più e più volte al momento della creazione delle istanze.