view Lib/IMPL/Object/Factory.pm @ 120:41e9d9ea3db5

Merge with 79cdd6c86409806bd1de092d9f0fb2b048775720
author wizard
date Mon, 07 Jun 2010 17:45:14 +0400 (2010-06-07)
parents 7084af955c57
children 4267a2ac3d46
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;
	public property method => prop_get | owner_set; 
}

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

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

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

sub CreateObject {
	my $this = shift;
	
	if (my $method = $this->method) {
		$this->factory->$method($this->parameters ? (_as_list($this->parameters),@_) : @_);	
	} else {
		$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

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

my $class = 'MyApp::User';

my $user;

$user = $class->new(name => 'nobody'); # will create object MyApp::User
                                       # and pass parameters (name=>'nobody')
											
$user = $factory->new(name => 'root'); # will create object MyApp::User
                                       # and pass paremeters (isAdmin => 1, name => 'root')

=end code

��� ��������������� ����� � XML.

=begin code xml

<factory type="IMPL::Object::Factory">
	<factory>MyApp::User</factory>,
	<parameters type="HASH">
		<isAdmin>1</isAdmin>
	</parameters>
</factory>

=end code xml

=head1 DESCRIPTION

C<[Serializable]>

�����, ����������� ������� �������.

������� ������� ��� ����� ������, ������� ����� ����� C< new > ����� �������� �������� � �������� ������
�������. �������� ������ ����� ��� �������� ��������, ���������, ���� � ���� ������� �����
C< new >, �� ����� ������ ������. ���������� �������, � ���� ���������� ����� Perl, �����
�������� ���������, ������ ��������, ��� � �����.

������ ����� ������ ��������� ������ C< new > � ����������� �� ��������� ������: ������������
������ ��� ������ �������. ��� ������ ������ C< new > � ������ ���������� �������� �������
������� � ������������� �����������. ����� ������-������� ����� ���� ������������ ��� ��������
�������� ��� �� ������ ���������� �������.

=head1 MEMBERS

=over

=item C< CTOR($factory,$parameters,$method) >

������� ����� ��������� �������.

=over

=item C<$factory>

���� ��� ������, ���� ������ �������.

=item C<$parameters>

������ �� ��������� ��� �������� ��������, ����� ���� ������� �� ���, ������ � �.�.

���� �������� ������� �� ���, �� ��� �������� �������� ������ �������� ���� ���
����� ��������� � ������ � ������� ����������� ������ C<new>.

���� �������� ������� �� ������, �� ��� �������� �������� ������ �������� ���� ������
����� ������� � ����� � ������� ����������� ������ C<new>.

���� �������� ����� ������ �������� ��� ��������, �� ����� ������� ���������� ������
C<new> ��� ����.

=item C<$method>

��� ������ (��� ������ �� ���������), ������� ����� ������ � C<$factory> ��� ��������
������� �������� ������ �������.

=back

=item C< [get] factory >

��������, ���������� ������� ��� �������� ����� �������� ������� ��������. ���� ����� ��� ��������
��� ������.

=item C< [get] parameters >

��������, �������� ������ �� ��������� ��� �������� ��������, ��� �������� ������� ��� ��������� �����
���������� � ������ � �������� ��������� C< new > ������� �� �������� C< factory >, �� ���� �����
��������� ��������� ��������������� ������� �������.

=item C<new(@params)>

������� ����� ������, ��������� ������� C<factory> ��� ������� � ��������� ���� ���������
�� �������� C<parameters> � ������ C<@params>. ���� �������� ���������� ������, ��� ��� ����������.

=begin code

sub new {
	my ($this,@params) = @_;
	
	my $method = $this->method || 'new';
	
	return $this->factory->$method(_as_list($this->parameters), @params);
}

=end code

=back

=cut