A froggy visitor

From CSSEMediaWiki
(Difference between revisions)
Jump to: navigation, search
(Added UML diagrams for visitor pattern application and Lukas' suggested solution.)
 
(6 intermediate revisions by 6 users not shown)
Line 1: Line 1:
Should a frog be able to export itself? For those that think not, the Visitor pattern may provide a solution. Figure 1 presents an application of the Visitor pattern structure to the [[Frogs design]], the interactions are described in Fig. 2. Here, the Exporter class and its child play the role of the visitor. The Frog class accepts visits from an Exporter object, then passes itself to the Exporter. The Exporter then performs operations using the Frog object. These operations are captured in the methods
+
Homework excercise for us!
*EggyExportOperation()
+
*TadpoleyExportOperation()
+
*AdultFroggyOperation()
+
Although, an Exporter is more likely to be interested in the attributes of a Frog object.
+
  
 +
This exercise was introduced during a discussion about this [[Frogs design]] example. The question was raised concerning the "exportXML()" method of the frog class:
  
[[image:AFroggyVisitorStructure.JPG|frame|centre|'''Figure 1: A [[UML 2.1]] [[Class diagram|class diagram]] describing an application of the Visitor structure to the [[Frogs design]]''']]
+
[[Image:Frog_export_exercise.gif]]
  
 +
Is this method good, evil, or the lesser of two evils?
  
[[image:AFroggyVisitorCommunication.JPG|frame|centre|'''Figure 2: A [[UML 2.1]] [[Communication diagram|communication diagram]] describing an application of the Visitor pattern interactions to the [[Frogs design]]''']]
+
* This method contradicts the [[Model the real world]] maxim. A frog does not know about exporting itself and should not be able to.
 +
 
 +
* If the frog did not know how to export itself then another class would need internal access to achieve this. However, this will break the [[Encapsulation boundary]].
 +
 
 +
Riel states [[Model the real world]] is often violated for keeping related data and behaviour in one place so the current exportXML may very well be the lesser of these two evils.
 +
 
 +
=Alternate Solutions=
 +
 
 +
A solution to this problem would involve
 +
* IExporter -- an interface defining:
 +
** An export method taking a property name and a property value (overloaded to support int, string, etc differently).
 +
** BeginSubsection and EndSubsection methods to allow them to export, for instance, their legs. They can BeginSubsection("leg1"), then ask their first leg to export itself, then End(the)Subsection()
 +
* Frog::Export(IExporter) -- a method exporting this frog to whatever format is passed in.
 +
* XmlExporter -- A basic implementation of IExporter which exports to an XML file. Would probably take a filename in the constructor.
 +
 
 +
[[image:FroggyExporter.gif|frame|centre|'''Figure 1: A UML [[Class diagram|class diagram]] describing the suggested solution structure''']]
 +
 
 +
 
 +
In this solution, the XmlExporter does not need to know about a frog, and the frog doesn't need to know  Xml -- but it does need to be able to export itself in a relatively generic fashion. I don't think that's too much to ask of a frog.
 +
 
 +
Advantages of this approach are: that it is
 +
* extensible for other types of exporters
 +
* keeps coupling relatively loose
 +
* the [[encapsulation boundary]] is preserved
 +
 
 +
----
 +
 
 +
Another solution is to apply the [[visitor pattern]] to this design.
 +
 
 +
[[image:FroggyVisitor.gif|frame|centre|'''Figure 2: A UML [[Class diagram|class diagram]] describing the application of the visitor pattern to this problem''']]
 +
 
 +
Advantages
 +
* A visitor of any type can be added (not just an exporter).
 +
* The frog has no knowledge of the implementation of the exporter or any other visitor
 +
 
 +
Disadvantages
 +
* Breaking [[encapsulation boundary|encapsulation]]: The frog's interface needs to be powerful enough to enable the exporter do its job.
 +
* Adding another type of frog requires another operation in all the visitors.

Latest revision as of 03:02, 18 July 2010

Homework excercise for us!

This exercise was introduced during a discussion about this Frogs design example. The question was raised concerning the "exportXML()" method of the frog class:

Frog export exercise.gif

Is this method good, evil, or the lesser of two evils?

  • This method contradicts the Model the real world maxim. A frog does not know about exporting itself and should not be able to.
  • If the frog did not know how to export itself then another class would need internal access to achieve this. However, this will break the Encapsulation boundary.

Riel states Model the real world is often violated for keeping related data and behaviour in one place so the current exportXML may very well be the lesser of these two evils.

Alternate Solutions

A solution to this problem would involve

  • IExporter -- an interface defining:
    • An export method taking a property name and a property value (overloaded to support int, string, etc differently).
    • BeginSubsection and EndSubsection methods to allow them to export, for instance, their legs. They can BeginSubsection("leg1"), then ask their first leg to export itself, then End(the)Subsection()
  • Frog::Export(IExporter) -- a method exporting this frog to whatever format is passed in.
  • XmlExporter -- A basic implementation of IExporter which exports to an XML file. Would probably take a filename in the constructor.
Figure 1: A UML class diagram describing the suggested solution structure


In this solution, the XmlExporter does not need to know about a frog, and the frog doesn't need to know Xml -- but it does need to be able to export itself in a relatively generic fashion. I don't think that's too much to ask of a frog.

Advantages of this approach are: that it is

  • extensible for other types of exporters
  • keeps coupling relatively loose
  • the encapsulation boundary is preserved

Another solution is to apply the visitor pattern to this design.

Figure 2: A UML class diagram describing the application of the visitor pattern to this problem

Advantages

  • A visitor of any type can be added (not just an exporter).
  • The frog has no knowledge of the implementation of the exporter or any other visitor

Disadvantages

  • Breaking encapsulation: The frog's interface needs to be powerful enough to enable the exporter do its job.
  • Adding another type of frog requires another operation in all the visitors.