Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
SOAP::WSDL::Generator:UseriContributed Perl DSOAP::WSDL::Generator::Visitor(3)

       SOAP::WSDL::Generator::Visitor -	SOAP::WSDL's Visitor-based Code

       SOAP::WSDL features a code generating facility. This code generation
       facility	(in fact there are several of them) is implemented as Visitor
       to SOAP::WSDL::Base-derived objects.

   The Visitor Pattern
       The Visitor design pattern is one of the	object oriented	design pattern
       described by [GHJV1995].

       A Visitor is an object implementing some	behaviour for a	fixed set of
       classes,	whose implementation would otherwise need to be	scattered
       across those classes' implementations.

       Visitors	are usually combined with Iterators for	traversing either a
       list or tree of objects.

       A Visitor's methods are called using the	so-called double dispatch
       technique.  To allow double dispatching,	the Visitor implements one
       method for every	class to be handled, whereas every class implements
       just one	method (commonly named "access"), which	does nothing more than
       calling a method	on the reference given,	with the self object as

       If all this sounds strange, maybe an example helps. Imagine you had a
       list of person objects and wanted to print out a	list of	their names
       (or address stamps or everything	else you like).	This can easily	be
       implemented with	a Visitor:

	   package PersonVisitor;
	   use Class::Std;    #	handles	all basic stuff	like constructors etc.

	   sub visit_Person {
	       my ( $self, $object ) = @_;
	       print "Person name is ",	$object->get_name(), "\n";

	   package Person;
	   use Class::Std;
	   my %name : ATTR(:name<name> :default<anonymous>);

	   sub accept {	$_[1]->visit_Person( $_[0] ) }

	   package main;
	   my @person_from = ();
	   for (qw(Gamma Helm Johnson Vlissides)) {
	       push @person_from, Person->new( { name => $_ } );

	   my $visitor = PersonVisitor->new();
	   for (@person_from) {

	   # will print
	   Person name is Gamma
	   Person name is Helm
	   Person name is Johnson
	   Person name is Vlissides

       While using this	pattern	for just printing a list may look a bit	over-
       sized, it may become handy if you need multiple output formats and
       different classes to operate on.

       The main	benefits using visitors	are:

       o   Grouping related behaviour in one class

	   Related behaviour for several classes can be	grouped	together in
	   the Visitor class. The behaviour can	easily be changed by changing
	   the code in one class, instead of having to change all the visited

       o   Cleaning up the data	classes' implementations

	   If classes holding data also	implement several different output
	   formats or other (otherwise unrelated) behaviour, they tend to get

       o   Adding behaviour is easy

	   Swapping out	the visitor class allows easy alterations of
	   behaviour. So on a list of Persons, one Visitor may print address
	   stamps, while another one prints out	a phone	number list.

       Of course, there	are also drawbacks in the visitor pattern:

       o   Changes in the visited classes are expensive

	   If one of the visited classes changes (or is	added),	all visitors
	   must	be updated to reflect this change. This	may be rather
	   expensive if	classes	change often.

       o   The visited classes must expose all data required

	   Visitors may	need to	use the	internals of a class. This may result
	   in fidelling	with a object's	internals, or a	bloated	interface in
	   the visited class.

       Visitors	are usually accompanied	by a Iterator. The Iterator may	be
       implemented in the visited classes, in the Visitor, or somewhere	else
       (in the example it was somewhere	else).

       The Iterator decides which object to visit next.

   Why SOAP::WSDL uses the Visitor pattern for Code Generation
       Code generation in SOAP::WSDL means generating various artefacts:

       o   Typemaps

	   For every WSDL definition, a	Typemap	is created. The	Typemap	is
	   used	later as an aid	in parsing the SOAP XML	messages.

       o   Type	Classes

	   For every type defined in the WSDL's	schema,	a Type Class is

	   These classes are instantiated later	as a result of parsing SOAP
	   XML messages.

       o   Interface Classes

	   For every service, a	interface class	is generated. This class is
	   later used by programmers accessing the service

       o   Documentation

	   Both	Type Classes and Interface Classes include documentation.
	   Additional documentation may	be generated as	a hint for
	   programmers,	or later for mimicking .NET's .asmx example pages.

       All these behaviours could well be (and have historically been)
       implemented in the classes holding the WSDL data. This made these
       classes rather bloated, and made	it hard	to change behaviour (like
       supporting SOAP Headers,	supporting atomic types, and other features
       which were missing from early versions of SOAP::WSDL).

       Implementing these behaviours in	Visitor	classes	eases adding new
       behaviours, and reducing	the incompletenesses still inherent in
       SOAP::WSDL's WSDL and XML schema	implementation.


       SOAP::WSDL::Base	defines	an accept method which expects a Visitor as
       only parameter.

       The method visit_Foo_Bar	is called on the visitor, with the self	object
       as parameter.

       The actual method name is constructed this way:

       o   SOAP::WSDL is stripped from the class name

       o   All remaining  :: s are replaced by _


       When visiting a SOAP::WSDL::XSD::ComplexType object, the	method
       visit_XSD_ComplexType is	called on the visitor.

   Writing your	own visitor
       SOAP::WSDL eases	writing	your own visitor. This might be	required if
       you need	some special output format from	a WSDL file or want to feed
       your own	serializer/deserializer	pair with custom configuration data.
       Or maybe	you want to generate C#	code from it...

       To write	your own code generating visitor, you should subclass
       SOAP::WSDL::Generator::Visitor. It implements (empty) default methods
       for all SOAP::WSDL data classes:

       o   visit_Definitions

       o   visit_Binding

       o   visit_Message

       o   visit_Operation

       o   visit_OpMessage

       o   visit_Part

       o   visit_Port

       o   visit_PortType

       o   visit_Service

       o   visit_SoapOperation

       o   visit_Types

       o   visit_XSD_Schema

       o   visit_XSD_ComplexType

       o   visit_XSD_Element

       o   visit_XSD_SimpleType

       In your Visitor,	you must implement visit_Foo methods for all classes
       you wish	to visit.

       The SOAP::WSDL::Generator::Visitor implementations include part of
       their own Iterator (which means they know how to	find the next objects
       to visit). You may or may not choose to implement a separate Iterator.

       Letting a visitor implementing its own Iterator visit a WSDL definition
       is as easy as writing something like this:

	my $visitor = MyVisitor->new();
	my $parser = SOAP::WSDL::Expat::WSDLParser->new();
	my $definitions	= $parser->parse_file('my.wsdl'):

	$definitions->_accept( $visitor	);

       If you need an iterator following the somewhat crude path of
       dependencies in a WSDL1.1 definition, you might want to look at

       o   [GHJV1995]

	   Erich Gamma,	Richard	Helm, Ralph E. Johnson,	John Vlissides,
	   (1995): Design Patterns. Elements of	Reusable Object-Oriented
	   Software.  Addison-Wesley Longman, Amsterdam.

       Copyright 2004-2008 Martin Kutter.

       This file is part of SOAP-WSDL. You may distribute/modify it under the
       same terms as perl itself

       Martin Kutter <martin.kutter>

	$Rev: 391 $
	$LastChangedBy:	kutterma $
	$Id: 391 2007-11-17 21:56:13Z	kutterma $
	$HeadURL: $

perl v5.32.0			  2020-01-20 SOAP::WSDL::Generator::Visitor(3)


Want to link to this manual page? Use this URL:

home | help