U E D R , A S I H C RSS

Gof/Visitor


1. Visitor

1.1. Intent

object structure �� element���� ������ operation �� ������. Visitor�� �� operation �������� element�� class�� �� �� operation�� ���� ������ ��.

1.2. Motivation

������ abstact syntax tree�� ����그���� ������고 ��. �������� �� ���� ��� ������ �� ����� �과 � '���� ����' ������ �� abstract syntax tree�� operation�� ������� ���� ���. �������� ��� code �� ��� ����. ���������� type-checking, code optimization, flow analysis �� ��� ����기 �� ���������� ���� ���� ����기 ���� �� operations���� ������� ����. �� ���� ������ pretty-printing, program restructuring, code instrumentation, 그��고 ����그���� ����� 기���� � 계���� �기 �� abstract syntax tree�� ��� ���.

��� operations���� ���� variable���� arithmetic expression���� ������ node��과 ��assignment statement���� ������ node�� ��급��� ����. ������, 각각 assignment statement �� ������, variable �� ��근 �기 ������, arithmetic expression�� �������� ��� ���. ��� node class�� ���� �� ���� ������, ������ ���� �� �� ����.


���� Node class 계��구���� ������ ����. ��기���� ������ ����� node class���� ���� ��� operation���� ���� ���������� ��금 �기 ��고, ���거�� ������ ��꾸기 ����게 ��. Node �� type-checking ����� pretty-printing code�� flow analysis code��과 ���� ���� � ��������. 게��� �� operation�� ����기 ������ ���������� �������� ��������. ���� 각각�� � operation ���������� ����� �� ��고, node class�� operation���� �������� ���� ���� ���.

������ 각각�� ���������� ����� operation���� �����고, traverse �� (tree �� 각 node���� ) abstract syntax tree�� element����게 ������ ��겨�� �� ����. �� visitor��고 ��. element� visitor�� 'accepts' � element�� element�� ������ ������� visitor��게 request�� ����. request ���� element�� ������ ���고 ����. 그�� visitor�� �� element�� � operation�� ����� ���.

��������, visitor�� �� �� �������� �������� abstact syntax tree�� TypeCheck operation�� ���������� type-check �� ����� ���. 각각�� node�� node������ TypeCheck�� ���������� TypeCheck�� 구��� ���. (�� class diagram ����). ���� visitor�� ����, TypeCheckingVisior�� ���� ��, TypeCheckingVisitor�� ������ ��겨���� abstract syntax tree�� Accept operation�� ����� ���. 각각�� node�� visitor�� ���� ���������� Accept�� 구��� ��� (���� ��, assignment node�� 경�� visitor�� VisitAssignment operation�� ����� �고, varible reference�� VisitVaribleReference�� ����� ���.) AssignmentNode ������ TypeCheck operation �� TypeCheckingVisitor�� VisitAssignment operation���� �� ���.

type-checking �� 기���� �� �������� visitor�� ����기 ������ abstract syntax tree�� �� visitor���� ��� abstract parent class�� NodeVisitor ����. NodeVisitor�� 각 node class���� ���� operation���� ����. �� ����그���� 기 ���� 계���기 ���� application node class �� application-specific������ ����� ��, 그NodeVisitor�� �� subclass�� �� ����. VisitorPattern �� Visitor ����� ������ ������ 구������ ��� operation���� ������.



VisitorPattern����, 개������ ��개�� ���� 계���� ����. ���� operation ������ element�� � 계��고 (Node hierarchy), ���� element�� � operation���� ���� visitor����. (NodeVisitor hierarchy). 개������ visitor hierarchy �� �� subclass�� ��������� � operation�� ���� �� ����.

1.3. Applicability

VisitorPattern ����과 ����� ����.


1.5. Participants

  • Visitor (NodeVisitor)
    - declares a Visit operations for each class of ConcreteElement in the object structure. The operation's name and signature identifies the class that sends the Visit request to the visitor. That lets the visitor determine the concrete class of the element being visited. Then the visitor can access the element directly through its particular interface.
  • ConcreteVisitor (TypeCheckingVisitor)
    - implements each operation declared by Visitor. Each operation implements a fragment of the algorithm defined for the corresponding class of object in the structure. ConcreteVisitor provides the context for the algorithm and stores its local state. This state often accumulates result during the traversal of the structure.
  • Element (Node)
    - defines an Accept operation that takes a visitor as an argument.
  • ConcreteElement (AssignmentNode, VariableRefNode)
    - implements an Accept operation that takes a visitor as an argument.
  • ObjectStructure (Program)
    - can enumerate its elements.

    - may provide a high-level interface to allow the visitor to visit its elements.

    - may either be a composite (See CompositePattern) or a collection such as a list or a set.


1.6. Collaborations

1.7. Consequences

template <class Item>
class Iterator {
	// ...
	Item CurrentItem () const;
};

class Visitor {
public:
	// ...
	void VisitMyType (MyType*);
	void VisitYourType (YourType*);
};

1.8. Implementation

class Visitor {
public:
	virtual void VisitElementA (ElementA*);
	virtual void VisitElementB (ElementB*);

	// and so on for other concrete elements
protected:
	Visitor ();
};

class Element {
public:
	virtual ~Element ();
	virtual void Accept (Visitor&) = 0;
protected:
	Element ();
};

class ElementA : public Element {
public:
	ElementA ();
	virtual void Accept (Visitor& v) { v.VisitElementA (this); }
};

class ElementB : public Element {
public:
	ElementB ();
	virtual void Accept (Visitor& v) { v.VisitElementB (this); }
};

class CompositeElement : public Element {
public:
	virtual void Accept (Visitor&);
private:
	List<Element*>* _children;
};

void CompositeElement::Accept (Visitor& v) {
	ListIterator<Element*> i (_children);

	for (i.First (); !i.IsDone(); i.Next ()) {
		i.CurrentItem ()->Accept (v);
	}
	v.VisitCompositeElement (this);
}

1.9. Sample Code


class Equipment {
public:
	virtual ~Equipment ();

	const char* Name () { return _name; } 
	
	virtual Watt Power ();
	virtual Currency NetPrice ();
	virtual Currency DiscountPrice ();

	virtual void Accept (EquipmentVisitor&);

protected:
	Equipment (const char*);
private:
	const char* _name;
};

class EquipmentVisitor {
public:
	virtual ~EquipmentVisitor ();

	virtual void VisitFloppyDisk (FloppyDisk*);
	virtual void VisitCard (Card*);
	virtual void VisitrChassis (Chassis*);
	virtual void VisitBus (Bus*);

	// and so on for other concrete subclasses of Equipment
protected:
	EquipmentVisitor ();
};

void FloppyDisk::Accept (EquipmentVisitor& visitor) {
	visitor.VisitFloppyDisk (this);
}

void Chassis::Accept (EquipmentVisitor& visitor) {
	for (ListIterator<Equipment*> i(_parts); !i.IsDone (); i.Next ()) {
		i.CurrentItem ()->Accept (visitor);
	}
	visitor.VisitChassis (this);
}

class PricingVisitor : public EquipmentVisitor {
public:
	PricingVisitor ();

	Currency& GetTotalPrice ();

	virtual void VisitFloppyDisk (FloppyDisk*);
	virtual void VisitCard (Card*);
	virtual void VisitChassis (Chassis*);
	virtual void VisitBus (Bus*);
	// ...
private:
	Currency _total;
};

void PricingVisitor::VisitFloppyDisk (FloppyDisk* e) {
	_total += e->NextPrice ();
}

void PricingVisitor::VisitChassis (Chassis* e) {
	_total += e->DiscountPrice ();
}

class InventoryVisitoy : public EquipmentVisitor {
public:
	InventoryVisitor ();

	Inventory& GetInventory ();

	virtual void VisitFloppyDisk (FloppyDisk*);
	virtual void VisitCard (Card*);
	virtual void VisitChassis (Chassis*);
	virtual void VisitBus (Bus*);
	// ...

private:
	Inventory _inventory;
};


void InventoryVisitor::VisitFloppyDisk (FloppyDisk* e) {
	_inventory.Accumulate (e);
}

void InventoryVisitor::VisitChassis (Chassis* e) {
	_inventory.Accumulate (e);
}

Equipment* component;
InventoryVisitor visitor;

component->Accept (visitor);
cout << "Inventory "
	<< componet->Name ()
	<< visitor.GetInventory ();


accept: aVisitor
	^ aVisitor visitSequence : self

visitSequence: sequenceExp
	inputState := sequenceExp expression1 accept: self.
	^ sequenceExp expression2 accept: self.

visitRepeat : repeatExp
	| finalState |
	finalState := inputState copy.
	[inputState isEmpty]
		whileFalse:
		[inputState := repeatExp repetition accept: self.
		finalState addAll: inputState].
	^ finalState

visitAlternation: alternateExp
	| finalState originalState |
	originalState := inputState.
	finalState := alternateExp alternative1 accept: self.
	inputState := originalState.
	finalState addAll: (alternateExp alternative2 accept: self).
	^ finalState

visitLiteral: literalExp
	| finalState tStream |
	finalState := Set new.
	inputState
		do:
			[:stream | tStream := stream copy.
				(tStream nextAvailable:
					literalExp components size
				) = literalExp components
					ifTrue: [finalState add: tStream]
			].
	^ finalState

1.10. Known Uses


Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:19
Processing time 0.0496 sec