64
|
1 package IMPL::Object::Factory;
|
|
2 use strict;
|
|
3
|
|
4 use base qw(IMPL::Object IMPL::Object::Serializable);
|
|
5
|
|
6 use IMPL::Class::Property;
|
|
7
|
|
8 BEGIN {
|
|
9 public property factory => prop_get | owner_set;
|
|
10 public property parameters => prop_get | owner_set;
|
|
11 }
|
|
12
|
|
13 # custom factory, overrides default
|
|
14 sub new {
|
|
15 my $self = shift;
|
|
16
|
|
17 return ref $self ? $self->CreateObject(@_) : $self->SUPER::new(@_);
|
|
18 }
|
|
19
|
|
20 sub CTOR {
|
|
21 my ($this,$factory,$parameters) = @_;
|
|
22
|
|
23 $this->factory($factory) or die new IMPL::InvalidArgumentException("The argument 'factory' is mandatory");
|
|
24 $this->parameters($parameters) if $parameters;
|
|
25 }
|
|
26
|
|
27 # override default restore method
|
|
28 sub restore {
|
|
29 my ($class,$data,$surrogate) = @_;
|
|
30
|
|
31 my %args = @$data;
|
|
32
|
|
33 if ($surrogate) {
|
|
34 $surrogate->callCTOR($args{factory},$args{parameters});
|
|
35 return $surrogate;
|
|
36 } else {
|
|
37 return $class->new($args{factory},$args{parameters});
|
|
38 }
|
|
39 }
|
|
40
|
|
41 sub CreateObject {
|
|
42 my $this = shift;
|
|
43
|
|
44 return $this->factory->new($this->parameters ? (_as_list($this->parameters),@_) : @_);
|
|
45 }
|
|
46
|
|
47 sub _as_list {
|
|
48 ref $_[0] ?
|
|
49 (ref $_[0] eq 'HASH' ?
|
|
50 %{$_[0]}
|
|
51 :
|
|
52 (ref $_[0] eq 'ARRAY'?
|
|
53 @{$_[0]}
|
|
54 :
|
|
55 $_[0]
|
|
56 )
|
|
57 )
|
|
58 :
|
|
59 ($_[0]);
|
|
60 }
|
|
61
|
|
62
|
|
63 1;
|
|
64
|
|
65 __END__
|
|
66
|
|
67 =pod
|
|
68
|
|
69 =head1 SYNOPSIS
|
|
70
|
|
71 =begin code
|
|
72
|
|
73 my $factory = new IMPL::Object::Factory(
|
|
74 'MyApp::User',
|
|
75 {
|
|
76 isAdmin => 1
|
|
77 }
|
|
78 );
|
|
79
|
67
|
80 my $class = 'MyApp::User';
|
|
81
|
|
82 my $user;
|
|
83
|
|
84 $user = $class->new(name => 'nobody'); # will create object MyApp::User
|
|
85 # and pass parameters (name=>'nobody')
|
|
86
|
|
87 $user = $factory->new(name => 'root'); # will create object MyApp::User
|
|
88 # and pass paremeters (isAdmin => 1, name => 'root')
|
|
89
|
64
|
90 =end code
|
|
91
|
67
|
92 Или сериализованная форма в XML.
|
|
93
|
|
94 =begin code xml
|
64
|
95
|
67
|
96 <factory type="IMPL::Object::Factory">
|
|
97 <factory>MyApp::User</factory>,
|
|
98 <parameters type="HASH">
|
|
99 <isAdmin>1</isAdmin>
|
|
100 </parameters>
|
|
101 </factory>
|
|
102
|
|
103 =end code xml
|
64
|
104
|
|
105 =head1 DESCRIPTION
|
|
106
|
67
|
107 C<[Serializable]>
|
|
108
|
64
|
109 Класс, реализующий фабрику классов.
|
|
110
|
|
111 Фабрика классов это любой объект, который имеет метод C< new > вызов которого приводит к созданию нового
|
|
112 объекта. Например каждый класс сам явялется фабрикой, поскольку, если у него вызвать метод
|
|
113 C< new >, то будет создан объект. Полученные объекты, в силу механизмов языка Perl, также
|
|
114 являются фабриками, притом такимиже, что и класс.
|
|
115
|
|
116 Данный класс меняет поведение метода C< new > в зависимости от контекста вызова: статического
|
|
117 метода или метода объекта. При вызове метода C< new > у класса происходит создание объекта
|
|
118 фабрики с определенными параметрами. Далее объект-фабрика может быть использована для создания
|
|
119 объектов уже на основе параметров фабрики.
|
|
120
|
|
121 =head1 MEMBERS
|
|
122
|
|
123 =over
|
|
124
|
67
|
125 =item C< CTOR($factory,$parameters) >
|
|
126
|
|
127 Создает новый экземпляр
|
|
128
|
|
129 =over
|
|
130
|
|
131 =item C<$factory>
|
|
132
|
|
133 Либо имя класса, либо другая фабрика.
|
|
134
|
|
135 =item C<$parameters>
|
|
136
|
|
137 Ссылка на параметры для создания объектов, может быть ссылкой на хеш, массив и т.д.
|
|
138
|
|
139 Если является ссылкой на хеш, то при создании объектов данной фабрикой этот хеш
|
|
140 будет развернут в список и передан параметрами методу C<new>.
|
|
141
|
|
142 Если является ссылкой на массив, то при создании объектов данной фабрикой этот массив
|
|
143 будет передан в списк и передан параметрами методу C<new>.
|
|
144
|
|
145 Если является любым другим объектом или скаляром, то будет передан параметром методу
|
|
146 C<new> как есть.
|
|
147
|
|
148 =back
|
|
149
|
|
150 =item C< [get] factory >
|
64
|
151
|
|
152 Свойство, содержащее фабрику для создание новых объектов текущей фабрикой. Чаще всего оно содержит
|
|
153 имя класса.
|
|
154
|
67
|
155 =item C< [get] parameters >
|
64
|
156
|
|
157 Свойство, содержит ссылку на параметры для создания объектов, при создании объекта эти параметры будут
|
|
158 развернуты в список и переданы оператору C< new > фабрике из свойства C< factory >, за ними будут
|
67
|
159 следовать параметры непосредственно текущей фабрики.
|
|
160
|
|
161 =item C<new(@params)>
|
|
162
|
|
163 Создает новый объект, используя свйство C<factory> как фабрику и передавая туда параметры
|
|
164 из свойства C<parameters> и списка C<@params>. Ниже приведен упрощенный пример, как это происходит.
|
|
165
|
|
166 =begin code
|
|
167
|
|
168 sub new {
|
|
169 my ($this,@params) = @_;
|
|
170
|
|
171 return $this->factory->new(_as_list($this->parameters), @params);
|
|
172 }
|
|
173
|
|
174 =end code
|
64
|
175
|
|
176 =back
|
|
177
|
|
178 =cut |