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

Reply via email to