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.
Ca exemplu, 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; }