NAME

Class::Wrapper - Decorator base class

SYNOPSIS

package SomeClass::Wrapper;
use base qw(Class::Wrapper);

# Overriding the default constructor
# Necessary only if new properties must be added
sub new {
  my ($class, $component) = @_;
  my $self = $class->SUPER::new($component);
  $self->{some_new_value} = "some default value";
  return $self;
}

# Modifying a method
sub some_method {
  my ($self) = @_;
  my $component = $self->_get_component();
  return 2 * $component->some_method();
}

# A new method
sub some_new_method {
  my ($self) @_;
  return $self->{some_new_value};
}

package main;

my $wrapper = SomeClass::Wrapper->new($some_object);
$wrapper->set_colour("red");# Setting "colour" attribute of $some_object
my $attribute = $wrapper->get_colour();# Retrieving value of attribute "colour" from $some_object
$wrapper->method_in_some_object();# Method call passed through to some object
my $value = $wrapper->some_method();# Call to overriding method in wrapper
my $other_value = $wrapper->some_new_method();

ABSTRACT

Class::Wrapper is a base module for decorators. Decorators are used to dynamically attach and detach responsibilities to an object. This is useful in a variety of situations when inheritance can't be used, or when inheritance would create too heavy objects.

DESCRIPTION

The Class::Wrapper constructor takes a single argument: the object it is going to decorate. Subclasses of Class::Wrapper may take more arguments though.

When a method is called on the Class::Wrapper object, it is executed if it has been declared. If the method has not been declared, a dispatch method is automatically created that passes the method call through to the underlying object.

As far as method calls go, the Class::Wrapper object behaves exactly like the underlying object. However, direct access to attributes does not work, because $wrapper-<gt{attribute}> would access attribute in the wrapper class, not in the underlying object. To handle this problem, Class::Wrapper autogenerates accessor (get_attributename/set_attributename) methods to access properties of the underlying object.

Making a Decorator Inherit the Component

In the original decorator pattern, a component and its decorators inherit the same abstract superclass. The advantage of doing this is that the decorators will then pass type checks using the isa() method.

It is possible to do this by having the decorator inherit both from Class::Wrapper and from the abstract component superclass (or directly from a concrete component, if there is no abstract superclass).

When the decorator inherits from the component, no dispatch methods will be autogenerated. Because of this, it is necessary to write explicit dispatch methods in the decorator for all methods in the component interface. A basic dispatch method looks like this:

sub some_method {
  my ($self, @args) = @_;
  return $self->_get_component(@args);
}

Public Methods

  • new

    my $wrapper = Class::Wrapper->new($component);

    The constructor takes the underlying component object as an argument and returns the decorator object.

Private Methods

  • _get_component

    my $component = $self->_get_component();

    The _get_component method returns the component object the decorator wraps. It can be used by methods in Class::Wrapper subclasses.

BUGS

None known.

SEE ALSO

None.

AUTHOR

Henrik Martensson, <henrik.martensson@aerotechtelub.se>

COPYRIGHT AND LICENSE

Copyright 2003 by Henrik Martensson

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.