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 inClass::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.