Perl/Moose OO design, package hierarchy
Asked Answered
O

2

12

I'm an average perl programmer. I haven't problem with the language itself, but with the "good" object design. While I'm able understand (most of) CPAN modules, without serious problems, i'm unable design myself even the simple object hierarchy.

Example - now facing an really simple application (web and command line interface):

  • the already authenticated student uploads a zip-file (what contains an rendering job)
  • unzip the file to and new directory and check it's content (should contain exatly one file commands.txt) and zero or more images
  • if the content is OK - move the directory to place called: JobRepository (another directory)
  • if the user decided to run the rendering job - send the job from his own JobRepository to global rendering queue (again, another directory)
  • another process takes the jobs from the queue (fifo - designed with IPC::DirQueue) and execute the rendering process
  • when finished, put the result into the users JobRepository/result directory
  • send email to the user
  • the student can download the zipped results

In bash it is doable with few "not to complicated" bash script - but i want do it in Perl (because web interface) - and want practice perlish (Moose) object design…

And here starts my problems.

Tried "visual" noun-analysis approach and make the next image.

enter image description here

Posted the image, because it is "shorter" as:

package Iren::JobRepo;
use Moose;
use warnings;
has 'Jobs' => (is => 'rw', isa=>ArrayRef[Iren::Job]);
…
method AddJob {
...
}

etc.

As you can see, it is really simple - but immediatelly facing some decision problems, e.g.:

  • what object should do the unzip/zip/checkJob methods? It is belong to: JobRepository ot the Job "zips" itself?
  • what object should send emails to User? the $user->send_email - comes me silly, because we sending email TO users and not the user to itself…
  • "who" should send the Job from the user's JobRepo to RenderQueue? The JobRepo->SendJobToRenderQueue or i should call some RenderQueue->addJob method?
  • what object should should use the ISA IPC::DirQueue - (should be the implememtation of RenderQueue)
  • circular definitions. The User has JobRepository, The Repository has many Jobs, but the Job has? an User? (need to know to whom belonging the job) - and so on..

As you can see, no Roles, no Traits here - nothing - it is simple… - but full of questions :(

Can anybody help clear the mess? What should be the "good" package hierarchy?

So, i'm really lost and I have started to disappointed myself. Additional questions (i know, these are opinion based) - but I must ask them...

  • How to learn good object design for perl/Moose? (I'm probably will never use another language)
  • searching google about object design (and Stackoverflow too) many times are cited the "Gand of Four" book (and few others). But usually for Java. It is worth to buy for the perl/Moose? Or is here some another good books for perl/Moose?
  • is some good technique how to check the proper object design?
  • code generators from UML probably doesn't exists for Moose - or is here something usable and recommented?
  • simply - how do you mastering your object hierarchy/Roles/Traits etc…? While i'm reading the examples - I understand the $cat->diets :) - but mastering something new - is bad for me…

Sorry for the wall of text. I would be much happy getting any pointer to good book or anything what helps...

Osteomyelitis answered 23/7, 2013 at 12:4 Comment(1)
+1 for doing great prep work and wish I could give a second +1 for caring about good object design.Irreverent
I
7

Stuff @daxim didn't answer:

  • How to learn good object design for perl/Moose? (I'm probably will never use another language)
  • Learn general OO design first (you seem to have good grasp on the basics)
  • Then learn about roles. They help simplify your design in a lot of cases and aren't part of Java OO so not typically covered in basic OO literature.
  • For Perl specific stuff, i would highly recommend cromatic's "Modern Perl" book as well as full contents of his Modern Perl blog. The book can be bought but IIRC is also available for free.
  • Also, to see where you don't need to use OO but other power of Perl, highly recommend that you read free "Higher Order Perl" book.
  • Make sure that for practical coding, one you understand the high level design things, you look into Moose (Moo) instead of Perl 5's native OO. Google for "moose presentation perl" for starters.
  • searching google about object design (and Stackoverflow too) many times are cited the "Gand of Four" book (and few others). But usually for Java. It is worth to buy for the perl/Moose? Or is here some another good books for perl/Moose?
  • is some good technique how to check the proper object design?

Frankly, the best way to check is: (1) Design review with a second pair of eyes and (2) see how your deign holds up to maintenance and reuse. Good design does NOT need to change much with every update. I'm not aware of any specific technical/procedural ways to check.

A good rule of thumb is: if you need to change ways something behaves, perhaps drastically, how much of your code will need to change? The best design is one that minimizes the changes.

  • simply - how do you mastering your object hierarchy/Roles/Traits etc…? While i'm reading the examples - I understand the $cat->diets :) - but mastering something new - is bad for me…

Practice. Ideally, find a problem solved by a tutorial/book, solve yourself first, then see how they solve it. Then post your best combined solution to codereview.SE and ask if it can be improved :)


circular definitions. The User has JobRepository, The Repository has many Jobs, but the Job has? an User? (need to know to whom belonging the job) - and so on..

No, you do NOT need to know whom the job belongs to. I explained why a couple of weeks ago - a VERY similar question was asked and answered by me here: OO Design Patterns with Perl .

Short version: In real code, you are very unlikely to ever start with a job without a user - by the time you get to the job, you most likely already started with a known user and got the job repository from that user. You don't need to re-find the user anymore.

Irreverent answered 23/7, 2013 at 13:28 Comment(0)
E
5

what object should do the unzip/zip/checkJob methods?

JobRepository

what object should send emails to User?

RenderQueue

i should call some RenderQueue->addJob method?

Yes, do it this way. The responsibility falls to the RenderQueue because it alone can decide whether to accept a job or not.

what object should should use the ISA IPC::DirQueue

Mu. Do not inherit, simply delegate.

The User has JobRepository

This is wrong, remove it.

but the Job has? an User?

Correct.


For the last two points of your design it would have helped immensely if you had drawn a ER diagram before UML.

Edward answered 23/7, 2013 at 13:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.