Excerpt from visitor mode in Design Mode

Source: Internet
Author: User

The 23 gof design modes are generally divided into three categories: Creation Mode, structure mode, and behavior mode.

The Creation Mode abstracts the instantiation process, which helps a system to create, combine, and express its objects independently. A class creation mode uses inheritance to change the class to be instantiated, while an object Creation Mode delegates the Instantiation to another object. The creation mode has two main themes. First, they all encapsulate information about the specific classes used by the system. Second, they hide how instances of these classes are created and put together. All objects in the system know interfaces defined by abstract classes. Therefore, the Creation Mode gives great flexibility in what is created, who creates it, how it is created, and when it is created. They allow you to configure a system with "product" objects with very different structures and functions. The configuration can be static (specified during compilation) or dynamic (at runtime ).

The schema involves how to combine classes and objects to obtain a larger structure. The structure class mode uses an Inheritance Mechanism to combine interfaces or implementations. The structured object mode not combines interfaces and implementations, but describes how to combine some objects to implement new functions. Because the object composite relationship can be changed at runtime, the object composite method has more flexibility, and this mechanism is impossible to achieve with static class composite.

The behavior pattern involves the assignment of duties between algorithms and objects. The behavior pattern not only describes the object or class pattern, but also describes the communication pattern between them. These modes depict complex control flows that are difficult to trace during runtime. They shift users' attention from the control flow to the contact information between objects. The behavior class mode uses the Inheritance Mechanism to distribute actions among classes. Behavior object mode uses Object combination instead of inheritance. Some behavior object modes describe how peer-to-peer objects collaborate to complete tasks that cannot be completed independently by any object.

The creation mode includes: 1. factorymethod (Factory method mode); 2. Abstract Factory (Abstract Factory mode); 3. Singleton (Singleton mode); 4. Builder mode and builder mode ); 5. Prototype (prototype ).

Structural modes include: 6. Bridge (Bridge Mode); 7. adapter (adapter mode); 8. decorator (decoration mode); 9. Composite (combination mode ); 10. flyweight (metadata mode); 11. facade (appearance mode); 12. Proxy mode ).

Behavior patterns include: 13. templatemethod (template method mode); 14. Strategy (Policy mode); 15. State (State mode); 16. Observer (Observer mode ); 17. Memento (memorandum mode); 18. mediator (intermediary mode); 19. Command (command mode); 20. Visitor (visitor mode ); 21. chain of responsibility (responsible chain mode); 22. iterator (iterator mode); 23. Interpreter (Interpreter mode ).

Factory method: Defines an interface for creating objects, so that the subclass determines which class to instantiate. Factory method delays the instantiation of a class to its subclass.

Abstract Factory: Provides an interface for creating a series of related or mutually dependent objects without specifying their specific classes.

Singleton: Ensure that a class has only one instance and provides a global access point to it.

Builder: Separates the construction of a complex object from its representation, so that different representations can be created during the same construction process.

Prototype: Use a prototype instance to specify the type of the object to be created, and copy the prototype to create a new object.

Bridge: Separates abstract parts from their implementations so that they can all change independently.

Adapter: Converts an interface of a class to another interface that the customer wants. The adapter mode allows the classes that cannot work together due to incompatibility of interfaces to work together.

Decorator: Dynamically add some additional responsibilities to an object. In terms of extended functions, the decorator mode is more flexible than the subclass generation method.

Composite: Combine objects into a tree structure to represent the "part-whole" hierarchy. Composite makes the customer's use of a single object and composite object consistent.

Flyweight: Use the sharing technology to effectively support a large number of fine-grained objects.

Facade: Provides a consistent interface for a group of interfaces in the subsystem. The facade mode defines a high-level interface, which makes the subsystem easier to use.

Proxy: Provides a proxy for other objects to control access to this object.

Template Method: Defines the skeleton of an algorithm in an operation, and delays some steps to the subclass. The template method allows the subclass to redefine certain steps of an algorithm without changing the structure of an algorithm.

Strategy: Define a series of algorithms, encapsulate them one by one, and make them replaceable. This mode makes the algorithm changes independent of the customers who use it.

State: Allows an object to change its behavior when its internal state changes. The object seems to have modified its class.

Observer: Defines a one-to-many dependency between objects, so that when the status of an object changes, all objects dependent on it will be notified and automatically refreshed.

Memento: Capture the internal state of an object without compromising encapsulation, and save the state outside the object. In this way, the object can be restored to the Saved state.

Mediator: Encapsulate a series of object interactions with an intermediary object. The intermediary makes the objects do not need to be explicitly referenced to each other, so that the coupling is loose and the interaction between them can be changed independently.

Command: Encapsulate a request as an object so that you can parameterize the customer with different requests, queue requests or record request logs, and support cancelable operations.

Visitor: Indicates an operation that acts on each element in an object structure. It allows you to define new operations that act on these elements without changing the classes of each element.

Chain of responsibility: To remove the coupling between the request sender and receiver, multiple objects have the opportunity to process the request. Connect these objects into a chain and pass the request along the chain until an object processes it.

Iterator: Provides a method to access each element in an aggregate object sequentially without exposing the internal representation of the object.

Interpreter: For a given language, define a representation of its syntax and define an interpreter that uses this representation to interpret sentences in the language.

Visitor: (1) Intention: represents an operation that acts on each element in an object structure. It allows you to define new operations that act on these elements without changing the classes of each element.

(2) Applicability: A. An object structure contains many class objects, which have different interfaces, and you want to perform operations on these objects dependent on their specific classes. B. You need to perform many different and unrelated operations on the objects in an object structure, and you want to avoid causing these operations to "pollute" the classes of these objects. Visitor allows you to define related operations in a class. When this object structure is shared by many applications, the visitor mode is used to allow each application to only include the required operations. C. Classes defining the object structure are rarely changed, but new operations are often needed in this structure. Changing the object structure class requires redefining the interfaces for all visitors, which may be costly. If the object structure class changes frequently, it may be better to define these operations in these classes.

(3) Advantages and Disadvantages: A. Visitor mode makes it easy to add new operations: Visitors make it easy to add operations of components dependent on complex object structures. You only need to add a new visitor to define a new operation in an object structure. On the contrary, if each function is distributed across multiple classes, each class must be modified when a new operation is defined. B. Separate irrelevant operations in a set of visitors: The related behaviors are not distributed in the classes that define the object structure, but in a single visitor. Unrelated behaviors are placed in their respective visitor subclasses. This simplifies the classes of these elements and the algorithms defined by these visitors. All data structures related to its algorithms can be hidden in visitors. C. It is difficult to add a new concreteelement class: the visitor mode makes it difficult to add a subclass of the new element. Each time a new concreteelement is added, a new abstract operation is added to the visitor, and corresponding operations are implemented in each concretevisitor class. Sometimes a default implementation can be provided in the visitor, which can be inherited by most concretevisitor, but this is not so much an exception as a rule. Therefore, when applying the visitor mode, the key question is which part of the system will change frequently. Is it the algorithm acting on the object structure or the class of each object in the structure. If a new concreteelement class is added, the visitor class hierarchy becomes difficult to maintain. In this case, it is easier to define these operations directly in the class that constitutes the structure. If the element class hierarchy is stable and you constantly add operations or modify algorithms, the visitor mode can help you manage these changes. D. Access through class layers: An iterator can traverse the entire object structure by calling specific operations of node objects and simultaneously access these objects. However, the iterator cannot operate on Object Structures with different element types. E. Cumulative state: When a visitor accesses every element in the object structure, it may accumulate state. If no visitor exists, this status is passed as an additional parameter to the traversal operation, or is defined as a global variable. F. Destroy encapsulation: visitors cannot assume that the concreteelement interface is powerful enough to allow visitors to perform their work. As a result, this mode often forces you to provide public operations to access the internal state of the element, which may damage its encapsulation.

(4) related mode: A. Composite: visitors can operate on an object structure defined by composite mode. B. Interpreter: the visitor can use it for explanation.

(5) Visitor mode is suitable for systems with stable data structures. It separates the data structure from the operations acting on the data structure so that the operation set can be made. Advantage: it is easy to add a new operation, because adding a new operation is equivalent to adding a visitor. The visitor mode aggregates the related behavior into a visitor object.

(6) The visitor mode provides new operations for the class without damaging the class. The key of the visitor mode is the double-dispatch technology. The C ++ language supports single assignment. Double dispatch means that the operation executed depends on the type of the request and the type of the receiver.

(7) The visitor mode allows the element to add new operations without modifying itself, but it also brings at least two notable problems: A, destroys encapsulation: the visitor mode requires that the visitor can modify the status of the element object from the outside, which is generally implemented in two ways. I. The element provides sufficient public interfaces so that the visitor can modify the element state by calling these interfaces. II. The element exposes more details to the visitor, or let the element provide the public implementation to the visitor (and of course other objects in the system), or declare the visitor as the element's friend class, and only expose the details to the visitor. But in either case, especially the latter, the encapsulation principle will be broken (in fact, the C ++ friend mechanism has been criticized by many object-oriented experts ). B. concreteelement expansion is very difficult: every time an element subclass is added, the visitor interface must be modified to provide the access mechanism for this new subclass. You can also add a visit () interface to process new classes, or reload a visit () operation to process new classes, or modify rtti (runtime type recognition: runtime type identification) visit () implementation. Either method makes it difficult to extend the new element subclass. Rtti provides simple consistency for the interface, but the price is time (implementation of rtti) and hard coding of code (forced conversion is required ).

Sample Code 1:

# Include <iostream> # include <string> # include <vector> using namespace STD; class man; class woman; // action class action {public: virtual void getmanconclusion (MAN * concreteelementa) = 0; virtual void getwomanconclusion (woman * concreteelementb) = 0 ;}; // successful class success: public action {public: virtual void getmanconclusion (MAN * concreteelementa) {cout <"when a man succeeds, there is a great woman behind it" <Endl;} virtual void getwomanconclusion (Woman * Concreteelementb) {cout <"when a woman succeeds, there is a useless man behind it" <Endl ;}}; // Failed class failure: public action {public: virtual void getmanconclusion (MAN * concreteelementa) {cout <"when a man fails, there is a great woman behind it" <Endl;} virtual void getwomanconclusion (woman * concreteelementb) {cout <"when a woman fails, there is a useless man behind it" <Endl ;}}; // Abstract Human class person {public: Virtual void accept (Action * visitor) = 0 ;}; // man class man: public person {public: Virtual void accept (Action * Visitor) {visitor-> getmanconclusion (this) ;}}; // woman class woman: public person {public: Virtual void accept (Action * visitor) {visitor-> getwomanconclusion (this) ;}}; // class objectstructure of the object structure class {PRIVATE: vector <person *> m_personlist; public: void add (person * P) {m_personlist.push_back (p);} void display (Action * A) {vector <person *>: iterator P = m_personlist.begin (); While (P! = M_personlist.end () {(* P)-> Accept (a); P ++ ;}}; // client int main () {objectstructure * OS = new objectstructure (); OS-> Add (New Man (); OS-> Add (New Woman ()); success * success = new success (); OS-> display (SUCCESS); Failure * FL = new failure (); OS-> display (FL ); /* result when a man succeeds, there is a great woman behind the scenes. When a useless man fails, there is a great woman behind the scenes, there is a useless man behind the scenes */return 0 ;}

Sample Code 2:

Visitor. h:

#ifndef _VISITOR_H_#define _VISITOR_H_class ConcreteElementA;class ConcreteElementB;class Element;class Visitor{public:virtual ~Visitor();virtual void VisitConcreteElementA(Element* elm) = 0;virtual void VisitConcreteElementB(Element* elm) = 0;protected:Visitor();private:};class ConcreteVisitorA : public Visitor{public:ConcreteVisitorA();virtual ~ConcreteVisitorA();virtual void VisitConcreteElementA(Element* elm);virtual void VisitConcreteElementB(Element* elm);protected:private:};class ConcreteVisitorB : public Visitor{public:ConcreteVisitorB();virtual ~ConcreteVisitorB();virtual void VisitConcreteElementA(Element* elm);virtual void VisitConcreteElementB(Element* elm);protected:private:};#endif//~_VISITOR_H_

Visitor. cpp:

#include "Visitor.h"#include "Element.h"#include <iostream>using namespace std;Visitor::Visitor(){}Visitor::~Visitor(){}ConcreteVisitorA::ConcreteVisitorA(){}ConcreteVisitorA::~ConcreteVisitorA(){}void ConcreteVisitorA::VisitConcreteElementA(Element* elm){cout<<"I will visit ConcreteElementA ..."<<endl;}void ConcreteVisitorA::VisitConcreteElementB(Element* elm){cout<<"I will visit ConcreteElementB ..."<<endl;}ConcreteVisitorB::ConcreteVisitorB(){}ConcreteVisitorB::~ConcreteVisitorB(){}void ConcreteVisitorB::VisitConcreteElementA(Element* elm){cout<<"I will visit ConcreteElementA ..."<<endl;}void ConcreteVisitorB::VisitConcreteElementB(Element* elm){cout<<"I will visit ConcreteElementB ..."<<endl;}

Element. h:

#ifndef _ELEMENT_H_#define _ELEMENT_H_class Visitor;class Element{public:virtual ~Element();virtual void Accept(Visitor* vis) = 0;protected:Element();private:};class ConcreteElementA : public Element{public:ConcreteElementA();~ConcreteElementA();void Accept(Visitor* vis);protected:private:};class ConcreteElementB : public Element{public:ConcreteElementB();~ConcreteElementB();void Accept(Visitor* vis);protected:private:};#endif//~_ELEMENT_H_

Element. cpp:

#include "Element.h"#include "Visitor.h"#include <iostream>using namespace std;Element::Element(){}Element::~Element(){}void Element::Accept(Visitor* vis){}ConcreteElementA::ConcreteElementA(){}ConcreteElementA::~ConcreteElementA(){}void ConcreteElementA::Accept(Visitor* vis){vis->VisitConcreteElementA(this);cout<<"visiting ConcreteElementA ..."<<endl;}ConcreteElementB::ConcreteElementB(){}ConcreteElementB::~ConcreteElementB(){}void ConcreteElementB::Accept(Visitor* vis){cout<<"visiting ConcreteElementB ..."<<endl;vis->VisitConcreteElementB(this);}

Main. cpp:

#include "Element.h"#include "Visitor.h"#include <iostream>using namespace std;int main(){Visitor* vis = new ConcreteVisitorA();Element* elm = new ConcreteElementA();elm->Accept(vis);/*resultI will visit ConcreteElementA ...visiting ConcreteElementA ...*/return 0;}

Visitor mode structure:


References:

1. Big talk Design Model C ++

2. Design Patterns-Analysis of gof23 Design Patterns

3. Design Patterns-Basics of reusable Object-Oriented Software

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.