Wzorce projektowe
odwiedzający
[wzorzec projektowy] Umożliwia wydzielenie zadań powiązanych logicznie ze sobą do osobnej klasy zwanej odwiedzającym. Odwiedzający może posiadać wiele implementacji zapewniając tym samym możliwość wykonania wielu różnych zadań. Dodawanie nowych zadań odbywa się bez ingerencji w elementy już oprogramowane.Opis szczegółowy
Odwiedzający
(ang. visitor) - wzorzec projektowy, który umożliwia wydzielenie zadań powiązanych logicznie ze sobą do osobnej klasy zwanej
odwiedzającym. Odwiedzający może posiadać wiele implementacji zapewniając tym samym możliwość wykonania wielu różnych zadań. Dodawanie nowych zadań odbywa się bez ingerencji w elementy już oprogramowane.
Wady
Zalety
Przykład
#include <string>
#include <vector>
#include <cstdio>
class CTextElement;
class CCommentElement;
class IVisitor
{
public:
virtual void visitElement( const CTextElement & element ) = 0;
virtual void visitElement( const CCommentElement & element ) = 0;
};
class IElement
{
public:
virtual void acceptVisitor( IVisitor & visitor ) = 0;
};
class CTextElement
: public IElement
{
public:
CTextElement( const char * sText )
: m_sText( sText ? sText
: "" )
{ }
const char * getText() const { return m_sText.c_str(); }
size_t getLength() const { return m_sText.size(); }
protected:
virtual void acceptVisitor( IVisitor & visitor ) { visitor.visitElement( * this ); }
private:
std::string m_sText;
};
typedef std::vector < IElement *> VElementsT;
class CCommentElement
: public IElement
{
public:
CCommentElement( const char * sText )
: m_sText( sText ? sText
: "" )
{ }
const char * getComment() const { return m_sText.c_str(); }
size_t getLength() const { return m_sText.size(); }
protected:
virtual void acceptVisitor( IVisitor & visitor ) { visitor.visitElement( * this ); }
private:
std::string m_sText;
};
class CDebugPrintElements
: public IVisitor
{
public:
virtual void visitElement( const CTextElement & element )
{
printf( "Tekst: %s {%d}\n", element.getText(), element.getLength() );
}
virtual void visitElement( const CCommentElement & element )
{
printf( "Komentarz: %s {%d}\n", element.getComment(), element.getLength() );
}
static void execute( VElementsT & vElements )
{
printf( "\n[Debug]\n" );
CDebugPrintElements visitor;
for( VElementsT::iterator it = vElements.begin(); it != vElements.end(); ++it )
( * it )->acceptVisitor( visitor );
}
};
class CPrintElements
: public IVisitor
{
public:
virtual void visitElement( const CTextElement & element )
{
printf( "%s\n", element.getText() );
}
virtual void visitElement( const CCommentElement & element )
{
printf( "/* %s */\n", element.getComment() );
}
static void execute( VElementsT & vElements )
{
printf( "\n[Release]\n" );
CPrintElements visitor;
for( VElementsT::iterator it = vElements.begin(); it != vElements.end(); ++it )
( * it )->acceptVisitor( visitor );
}
};
int main()
{
VElementsT vElements;
vElements.push_back( new CTextElement( "To jest tekst" ) );
vElements.push_back( new CCommentElement( "To jest komentarz" ) );
vElements.push_back( new CTextElement( "Koniec." ) );
CPrintElements::execute( vElements );
CDebugPrintElements::execute( vElements );
for(; !vElements.empty(); vElements.pop_back() )
delete vElements.back();
return 0;
}
Standardowe wyjście programu:
[Release]
To jest tekst
/* To jest komentarz */
Koniec.
[Debug]
Tekst: To jest tekst {13}
Komentarz: To jest komentarz {17}
Tekst: Koniec. {7}
Wszystkie teksty są chronione prawami autorskimi. Kopiowanie lub rozpowszechnianie treści poza niniejszym serwisem
jest zabronione.
Powyższe ograniczenie nie dotyczy autora opracowania, któremu przysługuje prawo do rozpowszechniania własnego tekstu wedle własnego uznania.