--- tags: Design Pattern --- # Visitor ## define: 訪問者模式( Visitor ),表示一個作用於某物件結構中的各元素之操作。它使你可以再不改變各元素之類別的前提之下,定義作用於這些元素的新操作。 -- Design Pattern by GoF [大話設計模式 p.434] Visitor mode ( Visitor ), which represents an operation that acts on each element in the structure of an object. It allows you to define new operations on elements without changing their class. -- Design Pattern by GoF [Dahua Design Patterns p.434] <font color="#f00">advantage:</font> 1. Separate processing from data <font color="#f00">disadvantage:</font> 1. Arbitrary use will lead to difficulties in data expansion --- ## time to use 在資料個數是固定的時候使用;可以在不影響的情況下擴充功能,每增加一個功能就會增加一個新的Visitor;但如果過度的使用的話會導致之後的維護困難。 It is used when the number of data is fixed; the function can be expanded without affecting it, and a new Visitor will be added for each additional function; but if it is used excessively, it will cause difficulty in subsequent maintenance. --- shape_visitor.h 定義visitor的範疇,這邊是把功能區分給圓形使用、給方形使用、給三角形使用以及給不規則形狀使用等等。 Define the category of visitor, here is to distinguish functions for circles, squares, triangles, and irregular shapes, etc. ```cpp= #pragma once class Circle; class Rectangle; class Triangle; class CompoundShape; class ShapeVisitor { public: virtual ~ShapeVisitor(){}; virtual void visitCircle(Circle *circle) = 0; virtual void visitRectangle(Rectangle *rectangle) = 0; virtual void visitTriangle(Triangle *triangle) = 0; virtual void visitCompoundShape(CompoundShape *compoundShape) = 0; protected: ShapeVisitor(){}; }; ``` --- shape_info_visitor.h 繼承至shape_visitor.h,他的職責是擴充元件的詳細資料查詢功能。 Inherited to shape_visitor.h, his responsibility is to expand the detailed information query function of components. ```cpp= #pragma once #include <string> #include <sstream> #include "./shape_visitor.h" #include "../circle.h" #include "../compound_shape.h" #include "../rectangle.h" #include "../triangle.h" class ShapeInfoVisitor : public ShapeVisitor { public: ShapeInfoVisitor() {} void visitCircle(Circle *circle) { for (int i = 0; i < depth; i++) { result += " "; } result = result + circle->info() + "\n"; } void visitRectangle(Rectangle *rectangle) { for (int i = 0; i < depth; i++) { result += " "; } result = result + rectangle->info() + "\n"; } void visitTriangle(Triangle *triangle) { for (int i = 0; i < depth; i++) { result += " "; } result = result + triangle->info() + "\n"; } void visitCompoundShape(CompoundShape *compoundShape) { for (int i = 0; i < depth; i++) { result += " "; } result += "CompoundShape{\n"; depth++; Iterator *it = compoundShape->createIterator(); for (it->first(); !it->isDone(); it->next()) { it->currentItem()->accept(this); } depth--; for (int i = 0; i < depth; i++) { result += " "; } depth--; result += "}\n"; } std::string getResult() { return result; }; private: int depth = 0; std::string result = ""; }; ``` --- test ```cpp= TEST(CaseShapeInfoVisitor, VisitTriangle) { TwoDimensionalVector vec1(3.0, 4.0); TwoDimensionalVector vec2(3.0, 0.0); Shape *t = new Triangle(vec1, vec2); ShapeInfoVisitor visitor; t->accept(&visitor); std::string result = visitor.getResult(); ASSERT_EQ("Triangle ([3.00,4.00] [3.00,0.00])\n", result); delete t; } ``` The relevant code is in: https://github.com/andy091045/Design-Pattern/tree/main/posd2021f_hw4/posd2021f_110598066_hw reference: https://ithelp.ithome.com.tw/articles/10208766