Administrativ
Laboratoare
Tema
Teste
Resurse utile
Alte resurse
Arhiva Teme
Administrativ
Laboratoare
Tema
Teste
Resurse utile
Alte resurse
Arhiva Teme
This is an old revision of the document!
Double-dispatch este o tehnică folosită în modelarea orientată-obiect atunci când avem de a face cu două categorii de obiecte (fiecare categorie conținând obiecte de tipuri diferite), între care există o interacțiune.
Fie aceste categorii de obiecte A
și B
, respectiv. Din punct de vedere obiectual, ierarhia de clase A
conține clasa A
și clasele A1
și A2
ca subclase ale lui A
. Fie, de asemenea, o ierarhie identică pentru B
. Ne dorim ca orice obiect de tip A
să poată interacționa cu orice obiect de tip B
, dar în mod diferit. Cu alte cuvinte, interacțiunea dintre un A1
și un B2
să fie diferită de cea dintre un A1
cu un B1
sau de cea dintre un A
cu un B2
. Presupunem, fără a restrânge generalitatea, că obiectele A
sunt cele care “acționează” efectiv asupra obiectelor B
.
O soluție care ar reieși imediat este în stilul următor. Toate obiectele de de tip A
ar putea avea o metodă public void interactiWith(B b)
, ca în snippet-ul de cod următor:
public class A { public void interactWith(B b) { if (b instanceof B1){ B1 realb = (B1) b; // ... // action for B1 } else if (b instanceof B2){ B2 realb = (B2) b; // ... // action for B2 } else { // ... // action for B } } }
Dacă fiecare subclasă a lui A
suprascrie metoda interactWith
și tratează fiecare caz pentru tipul efectiv al parametrului, atunci soluția ar fi completă: fiecare obiect A
ar avea propriile implementări pentru fiecare interacțiune, în funcție de tipul concret al obiectului B
primit ca parametru.
Soluția aceasta pare în regulă pentru scenariul nostru. Dar pentru că noi invățăm să gândim în perspectivă, ne punem întrebări: ce se întâmplă dacă (e nevoie să) adăugăm clase noi în oricare dintre ierarhii? Cum arată codul pentru ierarhii mai mari?
Să răspundem pe rând:
A
, atunci ea trebuie să suprascrie metoda interactsWith
, în același stil care tratează tipul efectiv al parametrului. Nu ar fi prea urât. Poate că ar fi, dacă avem multe tipuri B
.B
(fie ea B3
), atunci trebuie ca fiecare clasă din ierarhia A
să ia în calcul și noua variantă. Trebuie modificate toate metodele interactsWith
, din toată ierarhia A
, cu un nou instanceof
. Destul de urât. Ce ne facem dacă avem 100 de clase A
?A
.boolean isPrime(int n) { if (n == 2) return true; if (n == 3) return true; // ... if (n == 160480967) return true; // ... return false; }