OO Design Patterns with Perl

2019-05-06 18:18发布

问题:

I am currently planning the design for a new system I will need to code that interacts with a back-end API. I was contemplating object composition and inheritance and decided that the most correct procedure in my situation would be to go with composition over inheritance as my objects have a "has a" relationship to one another and not an "is a".

I find now though that because some objects are reliant on other, there may be cases were "object A" has an attribute which is "object B" and an attribute "object C" - however "object B" also has an attribute "object C".

In hope that this analogy would make more sense :

Lets say I have a company that sells boxes which contains cats and radioactive substance inside of them which may or may never react :

I sell my product to organizations. Users register with me by specifying an organization that they belong to. An organization may have many users or none. A user must have an organization that it belongs to. I keep track of my product (the box as an entity, and the cat(s) as an entity) and which organization they belong to. I also keep track of the cats and which boxes they are in. An organization may have many boxes with many cats in any of them. Boxes may be empty. Some users are allowed to buy new boxes whilst other are just allowed to look at them.

Authentication & Authorization is all managed by the API I interact with.

As far as object relationships go :

$user has a => $organization that it belongs to

$user has a => $role that dictates what it may or may not do.

$box has a => $organization that it belongs to

now:

$cat has a => $box that it belongs to 

AND

$cat has a => $organization that it belongs to ?

OR

$cat has a => $box that it belongs to WHICH has a => $organization that it belongs to

What would be the correct design decision here? Are there other aspects I'm not considering which may make one option more viable than the other?

I will be implementing an MVC design pattern in this system using Perl Catalyst and Moose.

Thank you all in advanced for your contributions.

回答1:

You gotta ask yourself one question. Does it matter to a cat which organization a cat or a box belongs to?

E.g., when you have a cat object, do you even need to know its owner? Is there a functionality that starts with a cat, and does something owner specific - WITHOUT knowing the owner before you even know the cat object?

E.g. a typical functionality would always start with a user:

my $org = $user->org();

Proceed to find its cats

my @cats = $org->listOwnedCats();

And then do something with one of the cats:

$cats[0]->CheckHealth();

Note the important fact: by the time you get to the specific cat - you already KNOW the organization since that was how you got the cat object in the first place. There's zero need to store $org inside the $cat object.

Same is true for the cats in boxes. Do you EVER need to find a cat's object's box aside from knowing that some cat isn't boxed yet?

If that functionality pattern holds (as it nearly always does), you have a VERY strait-forward object model:

  • User: Attributes are "org" and some other stuff
  • Org: Attributes are "UnboxedCatList" and "BoxList" - one is an array of cats that were not yet * assigned to boxes; one is an array of box objects
    • One of the methods is PlaceUnboxedCatIntoBox()
  • Box: Attributes are "CatList" (array of cat objects)
  • Cat: Attributes are cat specific - cat's don't own boxes or orgs.