in reply to Re-blessing || Re-constructing objects

Nearly every reason to rebless (including salva's example of Class:StateMachine) are better served with facades, especially as inside-out. For example:
package Facade::Base; sub new { my $class = shift; my ($main) = @_; return bless \$main, $class; } package Facade::One; use base 'Facade::Base'; sub example { my $self = shift; # foo() is a method on the object I expect to facade over $$self->foo( @args ); } package main; my $datastructure = Main::Class->new( %params ); my $facade1 = Facade::One->new( $datastructure ); # Now, I can call Facade::One's methods on $facade1. # I can also change the facade by doing something like: my $facade2 = Facade::Two->new( $$facade1 );

My criteria for good software:
  1. Does it work?
  2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

Replies are listed 'Best First'.
Re^2: Re-blessing || Re-constructing objects
by blogical (Pilgrim) on Apr 18, 2006 at 03:05 UTC
    Interesting. I hadn't heard of facade patterns (unsurprisingly) but the concept is simple enough. I would still be interested in an explanation of why facades are better, as I am new to them and perhaps can't fully grok the beauty of your example.

    "One is enough. If you are acquainted with the principle, what do you care for the myriad instances and applications?"
    - Henry David Thoreau, Walden

Re^2: Re-blessing || Re-constructing objects
by salva (Canon) on Apr 18, 2006 at 10:26 UTC
    I can't see why this facade aproach is a better solution other than because it doesn't rebless objects.

    In Perl 5, blessing is just a way to attach a dispatch table to some data structure. If I want my data structure to behave differently at different points in time the obvious solution is to change its dispatch table accordingly, so reblessing it.

      I suppose you could say that all OO is just a way to attach a dispatch table to some data structure. However, the other classes are not supposed to need to know what the actual data structure is, since they access it through methods. If you re-bless an object, your code (the part that does the re-blessing and the class you re-bless it into) will now break if the internals of the original class break, even if the API doesn't change.
        no, please, don't misunderstand me, I am not advocating into reblessing objects wildly from one class into another. I am just saying that doing it in a controlled manner is an useful mechanism and it can be used without breaking encapsulation or any other OOP property.

        Those controlled manners are at least two:

        • Reblessing an object into a descendant class of its current class. For instance, when you get new information about the object (BTW, in C++ this is done all the time under the hood at object construction time).
        • using several packages to implement a unique class that can change its behaviour dynamically, for instance:
          class TheHulk; sub new { bless $self, $class; $self->go_normal; $self; } sub go_normal { bless $self, TheHulk::_normal; } sub go_green { bless $self, TheHulk::_green; } sub relax {} sub make_angry {} package TheHulk::_normal; sub run { ... } sub make_angry { $self->go_green; } package TheHulk::_green; sub run { ... } sub relax { $self->go_normal; }
          three packages are used, but conceptually is just one class, so there is no messing with the internals of one class from another and the reblessing is always done from inside the class not from the outside.
        • any other?
      To paraphrase perrin, all I have to do is depend on the public (i.e., documented) API. I don't have to depend on how the object is implemented.

      I think the disconnect between how you're looking at things and how I am looking at things is I see OO as a set of behaviors that, when necessary, has some data to support those behaviors. You're looking at it as a data structure that may or may not have some behaviors associated with it. That's a pretty big disconnect.


      My criteria for good software:
      1. Does it work?
      2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?