Questo si riduce alla composizione e all'ereditarietà.
Diamo un'occhiata a uno schema che puoi eseguire in entrambi i modi.
Il adapter pattern
è, come suggerisce il nome, un adattatore tra due classi che sono altrimenti incompatibili.
Supponi di scrivere un motore 3D e hai bisogno di una classe Point
. Hai il tuo Point
tutto pronto e funziona, ma in alcune librerie trovi un'altra classe OtherPoint
che fa tutto ciò che la tua classe dovrebbe fare in modo più carino, ma i suoi metodi hanno nomi diversi. Il tuo motore 3D prevede la tua classe Point
.
Che cosa puoi fare per rendere entrambe le classi compatibili per poter utilizzare OtherPoint
class?
-
Point extends OtherPoint
ereditarietà per la vittoria. Point
riceve tutte le funzionalità di cui ha bisogno. I metodi specifici del tuo motore che Point
dichiara semplicemente chiamano quelli corrispondenti da OtherPoint
. Questo è lo stile modello di classe dell'adattatore.
- D'altra parte, potresti fare
Point(OtherPoint constructorParameter)
per ricevere un oggetto OtherPoint
. L'idea è simile: i metodi Point
ora non delegano ai metodi ricevuti tramite l'ereditarietà ma all'oggetto ricevuto come parametro nel costruttore. Questo è lo stile modello oggetto dell'adattatore. Questo è paragonabile al modello del wrapper.
In che modo ciò spiega le dichiarazioni di GoF?
"Class patterns [...] are static-fixed at compile-time.
Dicendo Point extends OtherPoint
tu dici che Point
è un OtherPoint
. È una semplice e semplice catena ereditaria. Non puoi cambiarli in fase di esecuzione.
Object patterns [...] which can be changed at run-time and are more dynamic
Dicendo Point(OtherPoint constructorParameter)
tu dici che Point
ha un OtherPoint
. Forse scopri che questa libreria ha una classe ancora più elaborata, cioè FancierOtherPoint extends OtherPoint
. Puoi passarlo anche a Point
. In effetti puoi passare qualsiasi sottolivello di OtherPoint
a Point
, a causa del polimorfismo.
Forse FancierOtherPoint
funziona solo su determinati hardware e devi controllare l'hardware in fase di esecuzione. Con lo stile modello oggetto dell'adattatore, puoi fare esattamente questo: decidi dinamicamente quale classe utilizzare.
I've never heard of "object relationships" outside of this book.
"relazioni oggetto" non è una frase speciale. Significa esattamente ciò che si dice: le relazioni tra gli oggetti. I modelli di progettazione sono solo nomi di modi comuni per definire le relazioni tra gli oggetti.
Se dovessi dire "3.14159265359 ..." probabilmente mi fermerai per chiedere se intendo "pi". Ora se dovessi dirmi che "erediti da quella classe per rendere le cose compatibili e delegare metodi e ..." vorrei fermarti a chiederti se intendi il modello dell'adattatore.
Semplifica la comunicazione e tutti hanno una comprensione approssimativa di cosa tratta la conversazione senza spiegare tutto in dettaglio.