Návrhový vzor visitor umožňuje pro danou skupinu tříd dynamicky definovat nové operace, aniž by bylo nutné tyto třídy jakkoliv modifikovat. Visitor řadíme mezi vzory chování (behavioral) a patří mezi Gang of Four (GoF) vzory (je obsažen v bibli návrhových vzorů Design Patterns: Elements of Reusable Object-Oriented Software).
Vzor visitor obsahuje dva typy tříd – třídy, které jsou navštěvované a třídy navštěvující (visitory). Navštěvované třídy v sobě nesou základní funkcionalitu, navštivující naopak přinášejí dynamicky (tj. za běhu aplikace) všem navštěvovaným třídám dodatečné chování.
Každá navštěvovaná třída musí být na příchod návštěvníka připravena – musí mít metodu (obvykle pojmenovanou accept) – která návštěvníka přijme a předá mu data, která potřebuje ke své práci. Jedná se o ukazatel na současnou instanci (this) a datové proměnné, ke kterým nemá návštěvník přístup (jsou například soukromé). Odkaz na aktuální instanci neslouží pouze k přenosu dat, rozhoduje také o tom, která metoda návštěvníka bude zavolána.
Představme si, že máme třídy obecního úřadu a krajské policejní správy (obě třídy dědí z třídy AbstractAuthority), dále máme návštěvníka, který přidává oběma úřadům schopnost vydávat výpis z rejstříku trestů. V okamžiku, kdy si občan zažádá o výpis z rejstříku obecní úřad, tak třída úřadu přijme odpovídajícího návštěvníka a předá mu potřebnou infrastrukturu. Metoda návštěvníka pro obecní úřad zjistí, která úřednice má nejméně práce a přidá jí vyřízení žádosti do úkolů na další den. Pokud by občan přišel na krajskou policejní, tak bude volána metoda specifická pro třídu (systém) policejní správy, která využije místní databáze a vrátí navštěvované třídě požadovaný dokument (výpis).
Ač se to není úplně patrné, tak nelze tento vzor implementovat jednodušeji – předat přetížené metodě visitor.visit abstraktního předka obou úřadů (AbstractAuthority) s tím, že se za běhu rozhodne dle skutečného typu parametru, zda-li bude volána metoda pro obecní úřad nebo policejní správu. Značná část programovacích jazyků totiž rozhoduje volání přetížených metod během kompilace. Pokud by tedy byl parametrem volání abstraktní předek, tak by se program ani nepřeložil (nešlo by rozhodnout, která metoda se má volat). Pokud by existovala varianta metody pro tohoto předka, tak by se program sice přeložil, ale byla by vždy volána jen pouze tato implementace (bez ohledu na to, že skutečným parametrem je jeden z potomků).
Tento nedostatek řeší výše uvedené double-dispatch schéma, ve kterém je nejprve volána metoda accept, která návštěvníkovi předá odkaz na aktuální instanci, pomocí něhož může bez problémů překladač rozhodnout, kterou variantu metody visit zavolat.
Do programu, který využívá vzoru visitor je velmi snadné přidat novou funkcionalitu, jelikož stačí vytvořit nového návštěvníka. Kdybychom chtěli přidat úřadům schopnost vydávat pasy, tak bychom jen vytvořili třídu PassportVisitor, která by měla metodu visit přetíženou pro oba typy úřadu a implementovala pro ně specifickou funkcionalitu.
Z opačné strany je velmi obtížné vytvořit novou rozšiřovanou třídu, jelikož to znamená úpravu všech stávajících návštěvníků – přidání odpovídající přetížené varianty metody visit.