in reply to Object Heirarchy / Design

Here's my take on it.

The idea behind your system, it seems to me, is that you want objects that are basically input-output neutral: they can be read from anywhere, and they can be written to anywhere. So what you want (and it sounds like what you have) is a series of polymorphic input and output drivers, such that you can provide a transparent transparent interface to the various input and output sources.

With that said, then, I would have one main object that doesn't inherit from anything. That object, in my system, would be of type "Obj". That's it. It would maintain *state* about its input and output drivers, so that when it came time to read and write this object, you could dispatch to the appropriate driver. So I might say:

my $obj = Obj->get('DB', @params);
and this would, under the hood, do the following: You could then set the output for your object, and do something much similar: load the proper class; call that class's "put" (or whatever) method.

The reason I would bless my object into Obj, rather than into a driver-specific input class, is that I find that confusing: your object is generic, and it's not tied to a particular input class. So why add restrictions that aren't already there?

With respect to inheritance, I'd have a main Obj class that inherits from nothing. That's your main object class. Then either one of two things:

I don't know which I'd choose. The second option feels cleaner to me. But then what do I know.

Replies are listed 'Best First'.
RE: RE: Object Heirarchy / Design
by lattice (Initiate) on Nov 15, 2000 at 06:33 UTC
    That sounds reasonable; my only question would be in regards to the actual calling syntax. It seems to me that Obj::Input::DB->get( @params ) is a bit clumsy, and I'd prefer to use something a bit more neutral, like a simple string passed as one of the arguments, eg:
    $myObj = Obj->get( "db", @args );
    I suppose i'm answering my own question here, since the above is almost identical in terms of implementation to
    $myObj = Obj::Input::DB->get( @params )
      That's easy enough. Just make Obj a wrapper around a more specific instance, like the DBI module you mention.
      package main; # example construction my $obj = Obj->new('Database', @parameters); my @data = $obj->get(@foo); package Obj; my %sources = { Database => Source::DB, XML => Source::XML, HTML => Source::HTML, }; sub new { my $class = shift; my $source = shift; my $source_obj = init($sources{$source}, @_); my $self = { source => $source_obj, }; bless($self, $class); } sub get { my $self = shift; return $self->{source}->get(@_); }
      Magic happens in the constructor :).

        While I agree with this in principle, I'm not sure I agree with the execution.

        I think that you'd really want Obj to return an instance of a subclass (e.g. Obj::DB or Obj::FlatFile).

        Then you maintain the consistency of the interface -- so that your objects all share the same methods and simply overload them as necessary, but the implementation specific to each type of object occurs in seperate classes/objects.

        I thought I remembered seeing something in Fastolfe's node, but I a quick look didn't come up with anything.