La composizione è quando una classe offre alcune funzionalità istanziando una classe (possibilmente interna) che già implementa questa funzionalità, invece di ereditare da quella classe.
Quindi, ad esempio, se hai una classe che modella una nave e ora ti viene detto che la tua nave dovrebbe offrire un eliporto, non è naturale derivare la tua nave da un eliporto, (duh!), Invece, dovresti avere la tua nave contiene una classe eliporto ed esponila con un Ship.getHelipad()
metodo.
Negli anni (circa un decennio fa) le persone erano solite considerare l'eredità come un modo semplice e veloce per aggregare la funzionalità, quindi c'erano molti esempi del tipo di "nave che eredita dall'eliporto", che erano, ovviamente, molto zoppi.
Ma il detto "Favor Composizione sull'ereditarietà" è stato attentamente formulato per chiarire che questo è solo un suggerimento, non una regola. L'autore del detto è stato abbastanza attento da astenersi dal dire qualcosa del tipo " non userai mai l' eredità, solo la composizione". Ciò sta sostanzialmente portando all'attenzione della comunità dell'ingegneria del software il fatto che l'ereditarietà è stata abusata, mentre in molti casi la composizione produce disegni più chiari, eleganti e sostenibili dell'eredità.
Quindi, in sostanza, il detto "Favor Composizione sull'ereditarietà" suggerisce che ogni volta che ti trovi di fronte a "ereditare o comporre?" domanda, dovresti pensare a fondo qual è la strategia più adatta e che la maggior parte delle probabilità è che la strategia più adatta si traduca in composizione, non ereditarietà.
Ma poiché questa non è una regola, dovresti anche tenere presente che ci sono molti casi in cui l'eredità è più naturale. Se usi la composizione lì dove avresti dovuto usare l'eredità, molti mali ricadranno sul tuo codice.
Per tornare all'esempio della nave, se la tua nave ha bisogno di offrire un'interfaccia per interagire con una FloatingMachine
, allora è più naturale derivarla da una FloatingMachine
classe astratta , che molto probabilmente potrebbe a sua volta derivare da un'altra Machine
classe astratta .
Ecco la regola empirica per la risposta alla composizione rispetto alla domanda di eredità:
La mia classe ha una relazione "is a" con l'interfaccia che deve esporre? Se sì, usa l'ereditarietà. In caso contrario, utilizzare la composizione.
Una nave "è una" macchina galleggiante e una macchina galleggiante "è una" macchina. Quindi, l'eredità va benissimo per quelli. Ma una nave non è, ovviamente, un eliporto. Quindi è meglio comporre la funzionalità dell'eliporto.