Composizione al posto dell'ereditarietà

Da Wikipedia, l'enciclopedia libera.
Jump to navigation Jump to search
Il diagramma mostra come il comportamento volo e suono di un animale può essere ideato in un modo flessibile attraverso l'uso del principio di progettazione della composizione al posto dell'ereditarietà.[1]

La composizione al posto dell'ereditarietà (o principio del riutilizzo dei composti) nella programmazione orientata agli oggetti è il principio che le classi dovrebbero ottenere il comportamento polimorfico e il riutilizzo del codice mediante la composizione (contenere altre classi che implementano la funzionalità desiderata), invece che attraverso l'ereditarietà (essere una sottoclasse).[2] Spesso questo è un principio dichiarato di OOP, come ad esempio nell'influente Design Patterns: "preferire la composizione di oggetti rispetto all'ereditarietà delle classi."[3]

Alcuni linguaggi, specialmente Go, usano esclusivamente questo tipo di composizione.

Le basi[modifica | modifica wikitesto]

Un'implementazione di composizione al posto dell'ereditarietà di solito inizia con la creazione di diverse interfacce che rappresentano i comportamenti che il sistema deve esibire. L'uso di interfacce permette a questa tecnica di supportare il comportamento polimorfico che è così importante nella programmazione orientata agli oggetti. Le classi che implementano le interfacce identificate sono sviluppate e aggiunte alle classi del dominio di applicazione secondo necessità. Così, i comportamenti del sistema sono realizzati senza l'ereditarietà. In realtà, le classi del dominio di applicazione possono essere tutte classi base, senza alcuna ereditarietà. L'implementazione alternativa dei comportamenti del sistema si realizza fornendo un'altra classe che implementa l'interfaccia col comportamento desiderato. Ogni classe del dominio di applicazione che contiene un riferimento all'interfaccia può supportare facilmente qualsiasi implementazione di tale interfaccia e la scelta può anche essere ritardata fino al tempo di esecuzione.

Vantaggi[modifica | modifica wikitesto]

Favorire la composizione al posto dell'ereditarietà è un principio di progettazione che offre al progettista maggiore flessibilità, realizzando nel lungo termine le classi del dominio di applicazione e un dominio di applicazione più stabile. In altre parole, una relazione del tipo "HA-UN" può essere migliore di una del tipo "È-UN".[1]

La progettazione iniziale è semplificata identificando i comportamenti del sistema nelle interfacce separate invece di creare una relazione gerarchica per distribuire i comportamenti tra le classi del dominio di applicazione con l'ereditarietà. Questo approccio può ospitare più facilmente futuri cambiamenti dei requisiti che altrimenti richiederebbero una ristrutturazione completa delle classi del dominio di applicazione nel modello di ereditarietà. Inoltre, evita problemi spesso associati con modifiche relativamente minori ad un modello basato dell'ereditarietà che comprende diverse generazioni di classi.

Svantaggi[modifica | modifica wikitesto]

Uno svantaggio nell'uso della composizione al posto dell'ereditarietà è che tutti i metodi essendo forniti dalle classi composte devono essere implementati nella classe derivata, anche se ci sono solo metodi di inoltro. Al contrario, l'ereditarietà non richiede che tutti i metodi di una classe base devono essere ri-implementati all'interno della classe derivata. Piuttosto, la classe derivata necessita solo di implementare (override) i metodi che hanno un comportamento differente rispetto ai metodi della classe base. Questo può richiedere significativamente meno sforzo di programmazione se la classe base contiene molti metodi che forniscono un comportamento predefinito e solo pochi di loro necessitano di essere sovrascritti all'interno della classe derivata.

Questo inconveniente può essere evitato utilizzando trait o mixin. Alcuni linguaggi, come Perl 6, forniscono una parola chiave di gestione per facilitare l'inoltro dei metodi. In Java, il progetto Lombok consente di implementare la delega utilizzando un'unica annotazione @Delegate sul campo invece di copiare e mantenere i nomi ed i tipi di tutti i metodi dal campo delegato.

Note[modifica | modifica wikitesto]

  1. ^ a b Eric Freeman, Elisabeth Freeman, Kathy Sierra e Bert Bates, Head First Design Patterns (paperback), a cura di Hendrickson e Mike Loukides, vol. 1, O'Reilly, 2004, p. 23, ISBN 978-0-596-00712-6.
  2. ^ Kirk Knoernschild, Java Design - Objects, UML, and Process: 1.1.5 Composite Reuse Principle (CRP), Addison-Wesley Inc., 2002. URL consultato il 23 maggio 2015.
  3. ^ Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides, Design Patterns, 1994, p. 20.