view Lib/IMPL/Config/Activator.pm @ 310:0a9d51cf6dfd

*TTView: refactoring, document supports custom classes, layouts are become controls
author sergey
date Fri, 19 Apr 2013 16:39:01 +0400
parents 8088779e539d
children
line wrap: on
line source

package IMPL::Config::Activator;
use strict;

use Scalar::Util qw(reftype);
use IMPL::lang;
use IMPL::Const qw(:prop);
use IMPL::declare {
	require => {
	   Loader => 'IMPL::Code::Loader',
	   Exception => 'IMPL::Exception'
	},
	base => [
	   'IMPL::Object' => undef,
	   'IMPL::Object::Autofill' => '@_',
	   'IMPL::Object::PublicSerializable' => undef
	],
	props => [
	   factory => PROP_RW,
	   parameters => PROP_RW,
	   singleCall => PROP_RW,
	   _object => PROP_RW
	]
};

use constant {
	SELF_CLASS => __PACKAGE__,
};

sub CTOR {
    my $this = shift;

    die Exception->new("A factory parameter is required") unless $this->factory;
    
}


sub activate {
    my $this = shift;
    
    unless ($this->_object) {
        my @args;
        
        my $params = $this->parameters;
        if (ref $params eq 'HASH') {
            while ( my ($key,$value) = each %$params ) {
                push @args,$key, is($value,SELF_CLASS) ? $value->activate : $value;
            }
        } elsif (ref $params eq 'ARRAY') {
            push @args, map is($_,SELF_CLASS) ? $_->activate : $_, @$params;
        } else {
            push @args, is($params,SELF_CLASS) ? $params->activate : $params;
        }
        
        push @args,  map is($_,SELF_CLASS) ? $_->activate : $_, @_ if @_;
        
        my $factory = $this->factory;
        Loader->default->Require($factory)
            unless ref($factory);
        
        my $instance = $factory->new(@args);
        
        $this->_object($instance)
            unless $this->singleCall;
        
        return $instance;
    } else {
        return $this->_object;
    }
}

1;

__END__

=pod

=head1 NAME

C<IMPL::Config::Activator> - объект, используемый для получения других объектов.

=head1 DESCRIPTION

Служит дополнительным уровнем абстракции в тех случаях, когда нужный объект
заранее не известен или его создание должно происходить по требованию.
От обычной фабрики отличается также тем, что рассматривает формальные параметры
на наличие активаторов и выполняет их при активации.

Кроме того можно указать, что процесс активации должен происходить при каждом
обращении. 

=cut