Re: Applying a role to an instance vs. subclassing

[email protected] (Jesse Luehrs)
Newsgroups perl.moose
Message-ID <[email protected]>
On Mon, Oct 08, 2012 at 07:08:09AM -0700, Bill Moseley wrote:
> I'm looking for some design ideas, and I'll try and briefly describe it.
> I suspect this is a Role vs. subclass question.
> 
> I have a job processing system where a set of one or more jobs are
> processed.   At the top I have a small class that has an ArrayRef of jobs
> and a method to "submit" the jobs for processing once they have all been
> gathered.  The jobs are processed independently, but they need to be
> submitted together.  (They are submitted to a pool of worker machines.)
> 
> It's the individual job class I have a question about.
> 
> A job has about five distinct stages of processing and uses a DBIx::Class
> row as a storage backend to maintain state.   The first state is before it
> has been "submitted" and doesn't have a job_id yet.   A notification
> message is sent when each job has completed a stage.   When I receive this
> message I need to recreate a job object, inspect the results of processing
> and then call a method to start the next stage of processing.
> 
> There's some common attributes -- after submitted every job has a unique
> job_id, and they all have a DIBx::Class row object.  They also to have
> connections to backend processing servers, etc.  But, each stage should
> have its own set of methods for dealing with just that one stage.
> 
> One approach is to create a base class with common methods and then create
> individual classes for each stage.   So, when I get a message that Stage #2
> has completed I might inspect the message to decide on the stage completed
> and then:
> 
>    my $class = 'Job::State::' . $message->{stage};  # stage1, stage2
>    my $job = $class->new;
> 
> Another approach is to have just a single class ( my $job = Job->new ) and
> then based upon state indicated by the message apply a role to that job
> instance that has the methods needed for handling the transition from one
> state to the next.
> 
> I think what I'd like best is to do is:
> 
>    my $job = Job->new( $message );
> 
> and have the $job essentially "know" what state it is in and only support
> methods for that state.
> 
> 
> Anyone have any guidance on how to structure classes like these?

This sounds like you really just want Job to be a factory instead.

  package Job;

  sub new_from_message {
      my $class = shift;
      my ($message) = @_;

      my $job_class = 'Job::State::' . $message->{stage};
      return $job_class->new;
  }

The individual state classes can use roles to share implementation if
you want, but I don't think this necessarily requires runtime role
application if you already have the classes written.

-doy
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.