Besökare
![]() | Den här artikeln behöver källhänvisningar för att kunna verifieras. (2020-12) Åtgärda genom att lägga till pålitliga källor (gärna som fotnoter). Uppgifter utan källhänvisning kan ifrågasättas och tas bort utan att det behöver diskuteras på diskussionssidan. |
Inom framför allt objektorienterad programmering möjliggör designmönstret besökare (Visitor pattern på engelska) en tydlig separation mellan en typstruktur och en beräkning på strukturen. Genom denna separation blir det lättare att lägga till nya operationer till befintliga strukturer utan att modifiera de ingående typerna. Det är med andra ord ett sätt att följa öppen/sluten-principen.
Exempel
Kärnan i ett 2D-CAD-program är dess geometri. Denna består av cirklar, linjer, bågar osv., grupperade i olika skikt. Tillsammans med ett antal ytterligare egenskaper bildar skikten en ritning -- den översta typen i en hierarki.
Att spara en ritning i programmets eget filformat är en grundläggande operation. Därmed kan det till en början kännas naturligt att implementera Save(..)-metoder i samtliga typer i hierarkin. Men stöd för andra filformat är också viktigt, och att fortsätta på samma spår genom att utöka varje typ med nya SaveAsXyz(...)-metoder, trasslar lätt till geometrityperna med oväsentliga detaljer om olika filformat. Det skulle också bryta mot en typ, ett ansvar-principen (eng. Single Responsibility Principle).
Ett rättframt sätt att lösa detta problem är genom separata funktioner för varje filformat. När några sådana funktioner skrivits syns dock ett tydligt mönster: alla innehåller likartade loopar och typcheckar, ett tydligt brott mot undvik-upprepningar-principen (eng. Don't Repeat Yourself). Om typerna är många är det dessutom relativt lätt att råka missa en viss geometrityp.
Det är här Besökarmönstret kommer till användning. Vad mönstret gör med koden är att kapsla en logisk operation för hela typträdet i en egen klass, med metoder för varje enskild typ. I vårt CAD-exempel skulle alltså varje filformat få en egen SaveXyz-typ, utan duplicering av loopar eller typcheckar någonstans. Dessutom skulle kompilatorn klaga om en viss geometrityp saknar implementation.
Se även
|