Stronę tą wyświetlono już: 3554 razy
Opis wzorca projektowego odwiedzający
Wzorzec projektowy odwiedzający należy do czynnościowych wzorców projektowych. Jego celem jest oddzielenie algorytmu od obiektu, na którym ów algorytm jest realizowany.
Przykładowy diagram UML wzorca projektowego odwiedzający
Na poniższym diagramie UML klasy Comment i Code dziedziczące po interfejsie iText mają zaimplementowaną metodę write, która to przyjmuje jako argument interfejs iCode. Interfejs ten jest dziedziczony przez klasy VBCode i CppCode mające zaimplementowaną metodę write w wersji przyjmującej jako argument referencje do obiektu klasy Code oraz w wersji przyjmującej jako argument obiekt klasy Comment. Interfejs iCode odwiedza obiekt klasy VBCode lub CppCode w celu wyświetlenia informacji w nim zawartych.
Przykładowa implementacja wzorca projektowego odwiedzający w C++
#include <iostream>
#include <string>
#include <vector>
class Code;
class Comment;
class iCode{
public:
virtual void write(Code &code) = 0;
virtual void write(Comment &comment) = 0;
virtual ~iCode(){}
};
class iText{
protected:
std::string text;
public:
iText(std::string text) : text(text){}
inline std::string getText() { return text; }
virtual void write(iCode* icode) = 0;
virtual ~iText(){}
};
class Code : public iText{
public:
Code(std::string text) : iText(text){}
virtual void write(iCode* icode){
icode->write(*this);
}
};
class Comment : public iText{
public:
Comment(std::string text) : iText(text){}
virtual void write(iCode* icode){
icode->write(*this);
}
};
class VBCode : public iCode{
public:
virtual void write(Code &code){
std::cout << "VB code: " << code.getText() << std::endl;
}
virtual void write(Comment &comment){
std::cout << "VB comment: " << comment.getText() << std::endl;
};
};
class CppCode : public iCode{
virtual void write(Code &code){
std::cout << "C++ code: " << code.getText() << std::endl;
}
virtual void write(Comment &comment){
std::cout << "C++ comment: " << comment.getText() << std::endl;
};
};
int main(){
std::vector<iText*> text;
text.push_back(new Comment("This is a line of comment in C++"));
text.push_back(new Code("int x = 0;"));
CppCode cppcode;
for(int i = 0; i < text.size(); i++){
text[i]->write(&cppcode);
}
while(!text.empty()){
delete text.back();
text.pop_back();
}
text.push_back(new Comment("This is a line of comment in VB"));
text.push_back(new Code("Dim x As Integer;"));
VBCode vbcode;
for(int i = 0; i < text.size(); i++){
text[i]->write(&vbcode);
}
while(!text.empty()){
delete text.back();
text.pop_back();
}
std::cin.get();
return 0;
}
Wynik działania powyższego kodu:
C++ comment: This is a line of comment in C++ C++ code: int x = 0; VB comment: This is a line of comment in VB VB code: Dim x As Integer;