package Encoder; ## Basic constructor sub new { my $type = shift; my $self = {}; bless $self, $type; } ## Define the common interface sub shared_stuff { return reverse $_[1]; } ## Define the uncommon interface sub other_stuff { die "Somebody didn't define the other stuff!"; } ## Generalized encoding method sub encode { my $self = shift; my ($text) = @_; $self->common_stuff($text); $self->other_stuff($text); } #### # In Encoder/B.pm package Encoder::B; use base 'Encoder'; sub other_stuff { my ($text) = @_; my $new_text = $text; $new_text =~ s/a/c/g; } #### use Encoder::B; use Encoder::Whatever; our %Encoder_Table => ( 'b' => 'Encoder::B', 'c' => 'Encoder::Whatever', ); sub encoder_factory { my ($e) = @_; exists $Encoder_Table{$e} or die "'$e' is not a valid type of encoder, sorry!"; return $Encoder_Table{$e}->new(); } #### my $encoder = encoder_factory($whatever_e_is); print $encoder->encode("Hahahaha!");