de.dante.extex.color
Interface ColorVisitor

All Known Implementing Classes:
PdfColorVisitor

public interface ColorVisitor

This interface implements part of the visitor pattern for colors.

In object-oriented design a pattern has been established to let one class react on the type of some object. Consider different color models represented in color objects of different types. All share a common base interface. This is the situation for Colors for which several types exist.

The original idea was to attach the desired functionality to the nodes and let it have one common method to invoke it. This turns out not to be practical for modular components where the algorithm might be exchanged. This is the case for the ColorConverter which might produce any converted Color in any other model. Any new implementation of the color interface would have the need to extend all Color classes.

The other simplistic solution is to use a large switch, or cascaded if-then-else, to differentiate the cases. This kind of code is cumbersome to maintain. Whenever a new type of node is added you have to remember all places which need adaption.

This problem is solved in the visitor pattern. Each class or interface of the colors has to provide one method called visit() here. This method has as one argument the visitor which should be called back. The visitor is defined by this interface. He has to provide a set of methods which allow him to differentiate the types of the colors.

Each color has to implement the method visit() in a way that the appropriate method from the visitor interface is invoked. Thus as a result the colors and the algorithm are decoupled.

The Mechanics of the ColorVisitor

A detailed description of the mechanics of a visitor can be found in the documentation for the NodeVisitor.

Example Source Code

Consider you have a class implementing DocumentWriter with a method which needs to react differently on different color types. The first approximation looks as follows:


 public class MyDocumentWriter implements DocumentWriter {

     public void myMethod(final Color color) {
         // Do something with color depending on its type
     }
 }
 

Now we can add the ColorVisitor interface. Thus we are forced to define a bunch of methods declared in this interface:


 public class MyDocumentWriter implements DocumentWriter, ColorVisitor {

     public void myMethod(final Color color) {
         // Do something with color depending on its type
     }
 
     public Object visitRgb(final RgbColor color, final Object arg) {
         // do something for RGB colors
     }

     public Object visitGray(final GrayscaleColor color, final Object arg) {
         // do something for grayscale colors
     }

     // and many others..
 
 }
 

Now we just have to make sure that those methods are invoked. This is done with the method visit() of the Color. The signature allows us to provide one additional argument and receive a return value. Since we want to do something with the color itself, this color is provided with the correct type to the color visitor. The second argument can be casted to the appropriate type.


 public class MyDocumentWriter implements DocumentWriter, ColorVisitor {

     public void myMethod(final Color color) {
         color.visit(this, "some value");
     }

     public Object visitRgb(final RgbColor color, final Object arg) {
         String s = (String) arg;
         // do something for RGB colors
     }

     public Object visitGray(final GrayscaleColor color, final Object arg) {
         String s = (String) arg;
         // do something for grayscale colors
     }

     // and many others..

 }
 

In the example above we have not used the additional argument or the return value. In the visit methods we are free to use them in all ways we like.

The definition of the parameters and the return value are rather general. Thus it is possible to use the visitor pattern in several different situations.

The visitor is not necessarily the class MyDocumentWriter. If this class contains several methods which need to distinguish the types of the colors it is possible to use another class as visitor, e.g. an inner class.

Version:
$Revision: 1.5 $
Author:
Gerd Neugebauer

Method Summary
 java.lang.Object visitCmyk(CmykColor color, java.lang.Object value)
          This method is called when an CmykColor has been encountered.
 java.lang.Object visitGray(GrayscaleColor color, java.lang.Object value)
          This method is called when an GrayscaleColor has been encountered.
 java.lang.Object visitHsv(HsvColor color, java.lang.Object value)
          This method is called when an HsvColor has been encountered.
 java.lang.Object visitRgb(RgbColor color, java.lang.Object value)
          This method is called when an RgbColor has been encountered.
 

Method Detail

visitCmyk

public java.lang.Object visitCmyk(CmykColor color,
                                  java.lang.Object value)
                           throws GeneralException
This method is called when an CmykColor has been encountered.

Parameters:
color - the first parameter for the visitor is the color visited
value - the second parameter is a visitor specific object
Returns:
the visitor specific value
Throws:
GeneralException - in case of an error

visitGray

public java.lang.Object visitGray(GrayscaleColor color,
                                  java.lang.Object value)
                           throws GeneralException
This method is called when an GrayscaleColor has been encountered.

Parameters:
color - the first parameter for the visitor is the color visited
value - the second parameter is a visitor specific object
Returns:
the visitor specific value
Throws:
GeneralException - in case of an error

visitHsv

public java.lang.Object visitHsv(HsvColor color,
                                 java.lang.Object value)
                          throws GeneralException
This method is called when an HsvColor has been encountered.

Parameters:
color - the first parameter for the visitor is the color visited
value - the second parameter is a visitor specific object
Returns:
the visitor specific value
Throws:
GeneralException - in case of an error

visitRgb

public java.lang.Object visitRgb(RgbColor color,
                                 java.lang.Object value)
                          throws GeneralException
This method is called when an RgbColor has been encountered.

Parameters:
color - the first parameter for the visitor is the color visited
value - the second parameter is a visitor specific object
Returns:
the visitor specific value
Throws:
GeneralException - in case of an error