view Lib/IMPL/Object/Factory.pm @ 64:259cd3df6e53

Doc generation Minor fixes
author wizard
date Mon, 15 Mar 2010 17:45:13 +0300
parents
children 9f5795a10939
line wrap: on
line source

package IMPL::Object::Factory;
use strict;

use base qw(IMPL::Object IMPL::Object::Serializable);

use IMPL::Class::Property;

BEGIN {
	public property factory => prop_get | owner_set;
	public property parameters => prop_get | owner_set; 
}

# custom factory, overrides default
sub new {
	my $self = shift;
	
	return ref $self ? $self->CreateObject(@_) : $self->SUPER::new(@_);
}

sub CTOR {
	my ($this,$factory,$parameters) = @_;
	
	$this->factory($factory) or die new IMPL::InvalidArgumentException("The argument 'factory' is mandatory");
	$this->parameters($parameters) if $parameters;
}

# override default restore method
sub restore {
	my ($class,$data,$surrogate) = @_;
	
	my %args = @$data;
	
	if ($surrogate) {
		$surrogate->callCTOR($args{factory},$args{parameters});
		return $surrogate;
	} else {
		return $class->new($args{factory},$args{parameters});
	}
}

sub CreateObject {
	my $this = shift;
	
	return $this->factory->new($this->parameters ? (_as_list($this->parameters),@_) : @_);
}

sub _as_list {
	ref $_[0] ?
		(ref $_[0] eq 'HASH' ?
			%{$_[0]}
			:
			(ref $_[0] eq 'ARRAY'?
				@{$_[0]}
				:
				$_[0]
			)
		)
		:
		($_[0]);
}


1;

__END__

=pod

=head1 SYNOPSIS

=begin code

sub ProcessItems {
	my ($factory,$items);
	
	return map $factory->new($_), @$items;
}

my @users = ProcessItems('MyApp::User',$db->selectUsers);

my $factory = new IMPL::Object::Factory(
	'MyApp::User',
	{
		isAdmin => 1
	}
);

=end code

my @admins = ProcessItems($factory,$db->selectAdmins);


=head1 DESCRIPTION

Класс, реализующий фабрику классов.

Фабрика классов это любой объект, который имеет метод C< new > вызов которого приводит к созданию нового
объекта. Например каждый класс сам явялется фабрикой, поскольку, если у него вызвать метод
C< new >, то будет создан объект. Полученные объекты, в силу механизмов языка Perl, также
являются фабриками, притом такимиже, что и класс.

Данный класс меняет поведение метода C< new > в зависимости от контекста вызова: статического
метода или метода объекта. При вызове метода C< new > у класса происходит создание объекта
фабрики с определенными параметрами. Далее объект-фабрика может быть использована для создания
объектов уже на основе параметров фабрики.

=head1 MEMBERS

=over

=item C< factory >

Свойство, содержащее фабрику для создание новых объектов текущей фабрикой. Чаще всего оно содержит
имя класса.

=item C< parameters >

Свойство, содержит ссылку на параметры для создания объектов, при создании объекта эти параметры будут
развернуты в список и переданы оператору C< new > фабрике из свойства C< factory >, за ними будут
следовать параметры непосредственно текущей фабрики. 

=back

=cut