You can have a Factory of Builders, but I fear I used too much imagination so the following might not be usable for your situation. It also doesn't make any sense for the simple situation I created, but that's how OO programming works - without particular objects and behaviours, it's all hand waving. It's hard to abstract from something that's already been abstracted.
#!/usr/bin/perl use warnings; use strict; use feature qw{ say }; { package MyClass; use Moo; has [qw[ id name data ]] => (is => 'ro', required => 1); sub job { my ($self) = @_; $self->data->{ $self->id } } } { package MyClass::Builder::FromElements; use Moo; has root => (is => 'ro'); sub build { my ($self, %data) = @_; return 'MyClass'->new(data => \%data, map +($_ => $self->root->findvalue("/r/$ +_")), qw( id name )) } } { package MyClass::Builder::FromAttributes; use Moo; has root => (is => 'ro'); sub build { my ($self, %data) = @_; return 'MyClass'->new(data => \%data, map +($_ => $self->root->findvalue("/r/\ +@$_")), qw( id name )) } } { package MyClass::Builder::Factory; use Moo; use XML::LibXML; has xml => (is => 'ro'); has _root => (is => 'lazy', init_arg => undef); sub build_builder { my ($self) = @_; if (2 == $self->_root->findvalue('count(/r/id | /r/name)')) { return MyClass::Builder::FromElements->new(root => $self-> +_root) } elsif (2 == $self->_root->findvalue('count(/r/@id | /r/@name +)')) { return MyClass::Builder::FromAttributes->new(root => $self +->_root) } else { die "Can't build.\n"; } } sub _build__root { my ($self) = @_; return 'XML::LibXML'->load_xml(string => $self->xml)->document +Element } } my %DATA = (12 => 'CEO', 14 => 'CTO'); for my $xml ( '<r><id>12</id><name>John</name></r>', '<r id="14" name="Jane"/>' ) { my $builder = 'MyClass::Builder::Factory'->new(xml => $xml)->build +_builder; my $o = $builder->build(%DATA); say join ', ', map $o->$_, qw( id name job ); }
In reply to Re: Using a factory class to return objects of the same class
by choroba
in thread Using a factory class to return objects of the same class
by Amblikai
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |