http://qs321.pair.com?node_id=11137360


in reply to OO Pattern Container x Elements and Method Chaining

OK, .. I hope an example makes it clearer

Container = SharedHouse Element = Person ->do_something = ->pay_rent

this used to work as long as one Person could only live in ONE house at a time.

my $cont = SharedHouse->new('Prag'); my $elem = Person->new('Egon'); $cont->add_elem($elem); # method chaining $cont->get_elem('Egon')->pay_rent();

Now the requirement changed to manage multiple houses in the same program with overlapping sets of inhabitants.

my best guess is that get_elem should now return an object of a new class Inhabitant pointing to one SharedHouse and one Person

like this, these would return different objects of type Inhabitant

$elem1 = $cont1->get_elem('Egon'); $elem2 = $cont2->get_elem('Egon');

but both are internally pointing to the same Person 'Egon'

$elem1->{person} == $elem2->{person}

such that

$elem1->pay_rent() pays the rent for the SharedHouse object in $cont1

but

$elem1->comb_hair() delegates to $elem1->{person}->comb_hair()

I hope it's clearer now. :)

(the real model is even more complicated, since the container is actually a matrix of two types of elements and values in the cell. Think of objects of type Room like $kitchen, and $Egon->owns("Kitchen", "Table"); )

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re^2: OO Pattern Container x Elements and Method Chaining (House, Person, Inhabitant)
by NERDVANA (Deacon) on Oct 09, 2021 at 13:54 UTC
    In 25 years of programming I have never actually run into a case where an element needed to know its container and also belong to multiple containers. *shrug*

    In most cases I’ve had where the element knew about its container, it was created and owned by the container, so there was no way to create it independent from the container, and the container was free to choose whether the element would be persistent using weak references, or temporary and only held by the strong reference given to the caller when they retrieve the object.

    If you have a sub X that needs to know about 2 objects, A and B, and A seems like a logical “container” and B seems like a thing that ought to be contained, then I would make A’s “get_B” return a temporary object C which holds strong references to A and B and has X as one of its methods.

    package A; use Moo; has ‘b_set’, is => ‘rw’; sub get_b($self, $name) { return C->new(a => $self, b => $self->b_set->{$name}); } package B; use Moo; sub do_thing_with_a($self, $a) { … } package C; use Moo; has ‘a’, is => ‘ro’; has ‘b’, is => ‘ro’, handles => [qw( … )]; # all of b’s methods sub do_thing($self) { $self->b->do_thing_with_a($self->a); }
      > In 25 years of programming

      Well I just dug up a book on OO modeling I bought about the same time ago, and it explicitly lists several object "associations" like this.

      If interested check on "aggregation", "composition", etc

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      as I said, there is legacy code which is using Method Chaining (I didn't design it)

      $house->get_member("Willy)->clean_house();

      Now the model changed and Person "Willy" can be member of different households

      > I have never actually run into a case where an element needed to know its container

      I have no idea how method chaining would be implemented else, since ->clean_house() is referring to $house

      In the new model case ->get_member() can't return a Person object anymore

      One possibility discussed here is to return a Wrapper-Object Inhabitant ° which wraps the relation

      'Person ->belongs_ to-> House'

      and delegates accordingly.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      °) update s/Member/Inhabitant/ for consistency to previous posts

      UPDATE

      regarding your suggestion, see Re^3: OO Pattern Container x Elements and Method Chaining

Re^2: OO Pattern Container x Elements and Method Chaining (House, Person, Inhabitant)
by karlgoethebier (Abbot) on Oct 09, 2021 at 12:10 UTC
    «…the real model is even more complicated…»

    Sure, yes as always in real life. But how does it really look? The «real model» I mean. It is just because I think sometimes oversimplification isn’t such a good idea. Regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

      Too complicated!

      (The Container holds Hierarchies and so called Attributes. A Hierarchy is a multi-tree of Elements. Elements and Attributes form a matrix (table) of Values.)

      > oversimplification isn’t such a good idea.

      SSCCE are

      But the problem I described is generic and isn't inherent to above model.

        Method Chaining with member objects becomes troublesome if the model evolves and member objects start to belong to multiple containers.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        «Too complicated!»

        Ja, ja. Programming on a mobile device is hard 🤪. BTW (and for further inspiration) you might take a look at Tree::MultiNode. Probably totally unrelated. But who knows. Regards, Karl

        «The Crux of the Biscuit is the Apostrophe»