Mercurial > pub > Impl
annotate Lib/IMPL/Object/Factory.pm @ 188:029c9610528c
Memory leak tests in IMPL::Web::View
author | cin |
---|---|
date | Tue, 03 Apr 2012 20:08:42 +0400 |
parents | 6c0fee769b0c |
children | 4d0e1962161c |
rev | line source |
---|---|
64 | 1 package IMPL::Object::Factory; |
2 use strict; | |
3 | |
166 | 4 use parent qw(IMPL::Object IMPL::Object::Serializable); |
64 | 5 |
181 | 6 use IMPL::lang qw(:declare :constants); |
64 | 7 |
8 BEGIN { | |
181 | 9 public property factory => PROP_GET | PROP_OWNERSET; |
10 public property parameters => PROP_GET | PROP_OWNERSET; | |
11 public property method => PROP_GET | PROP_OWNERSET; | |
64 | 12 } |
13 | |
14 # custom factory, overrides default | |
15 sub new { | |
16 my $self = shift; | |
17 | |
114
7084af955c57
minor changes, more strict code, no bugs fixed, no features added
wizard
parents:
91
diff
changeset
|
18 return ref $self ? $self->CreateObject(@_) : $self->IMPL::Object::new(@_); |
64 | 19 } |
20 | |
21 sub CTOR { | |
73 | 22 my ($this,$factory,$parameters,$method) = @_; |
64 | 23 |
24 $this->factory($factory) or die new IMPL::InvalidArgumentException("The argument 'factory' is mandatory"); | |
25 $this->parameters($parameters) if $parameters; | |
73 | 26 $this->method($method) if $method; |
64 | 27 } |
28 | |
29 # override default restore method | |
30 sub restore { | |
31 my ($class,$data,$surrogate) = @_; | |
32 | |
33 my %args = @$data; | |
34 | |
35 if ($surrogate) { | |
181 | 36 $surrogate->self::CTOR($args{factory},$args{parameters},$args{method}); |
64 | 37 return $surrogate; |
38 } else { | |
91 | 39 return $class->new($args{factory},$args{parameters},$args{method}); |
64 | 40 } |
41 } | |
42 | |
43 sub CreateObject { | |
44 my $this = shift; | |
45 | |
73 | 46 if (my $method = $this->method) { |
181 | 47 $this->factory->$method($this->MergeParameters(@_)); |
73 | 48 } else { |
186 | 49 $this->factory->new($this->MergeParameters(@_)); |
73 | 50 } |
64 | 51 } |
52 | |
181 | 53 sub MergeParameters { |
54 my $this = shift; | |
55 | |
56 $this->parameters ? (_as_list($this->parameters),@_) : @_; | |
57 } | |
58 | |
59 | |
64 | 60 sub _as_list { |
61 ref $_[0] ? | |
62 (ref $_[0] eq 'HASH' ? | |
63 %{$_[0]} | |
64 : | |
65 (ref $_[0] eq 'ARRAY'? | |
66 @{$_[0]} | |
67 : | |
68 $_[0] | |
69 ) | |
70 ) | |
71 : | |
72 ($_[0]); | |
73 } | |
74 | |
75 | |
76 1; | |
77 | |
78 __END__ | |
79 | |
80 =pod | |
81 | |
82 =head1 SYNOPSIS | |
83 | |
84 =begin code | |
85 | |
86 my $factory = new IMPL::Object::Factory( | |
87 'MyApp::User', | |
88 { | |
89 isAdmin => 1 | |
90 } | |
91 ); | |
92 | |
67 | 93 my $class = 'MyApp::User'; |
94 | |
95 my $user; | |
96 | |
97 $user = $class->new(name => 'nobody'); # will create object MyApp::User | |
98 # and pass parameters (name=>'nobody') | |
99 | |
100 $user = $factory->new(name => 'root'); # will create object MyApp::User | |
101 # and pass paremeters (isAdmin => 1, name => 'root') | |
102 | |
64 | 103 =end code |
104 | |
180 | 105 Или сериализованная форма в XML. |
67 | 106 |
107 =begin code xml | |
64 | 108 |
67 | 109 <factory type="IMPL::Object::Factory"> |
110 <factory>MyApp::User</factory>, | |
111 <parameters type="HASH"> | |
112 <isAdmin>1</isAdmin> | |
113 </parameters> | |
114 </factory> | |
115 | |
116 =end code xml | |
64 | 117 |
118 =head1 DESCRIPTION | |
119 | |
67 | 120 C<[Serializable]> |
121 | |
180 | 122 Класс, реализующий фабрику классов. |
64 | 123 |
180 | 124 Фабрика классов это любой объект, который имеет метод C< new > вызов которого приводит к созданию нового |
125 объекта. Например каждый класс сам явялется фабрикой, поскольку, если у него вызвать метод | |
126 C< new >, то будет создан объект. Полученные объекты, в силу механизмов языка Perl, также | |
127 являются фабриками, притом такимиже, что и класс. | |
64 | 128 |
180 | 129 Данный класс меняет поведение метода C< new > в зависимости от контекста вызова: статического |
130 метода или метода объекта. При вызове метода C< new > у класса происходит создание объекта | |
131 фабрики с определенными параметрами. Далее объект-фабрика может быть использована для создания | |
132 объектов уже на основе параметров фабрики. | |
64 | 133 |
134 =head1 MEMBERS | |
135 | |
136 =over | |
137 | |
73 | 138 =item C< CTOR($factory,$parameters,$method) > |
67 | 139 |
180 | 140 Создает новый экземпляр фабрики. |
67 | 141 |
142 =over | |
143 | |
144 =item C<$factory> | |
145 | |
180 | 146 Либо имя класса, либо другая фабрика. |
67 | 147 |
148 =item C<$parameters> | |
149 | |
180 | 150 Ссылка на параметры для создания объектов, может быть ссылкой на хеш, массив и т.д. |
67 | 151 |
180 | 152 Если является ссылкой на хеш, то при создании объектов данной фабрикой этот хеш |
153 будет развернут в список и передан параметрами методу C<new>. | |
67 | 154 |
180 | 155 Если является ссылкой на массив, то при создании объектов данной фабрикой этот массив |
156 будет передан в списк и передан параметрами методу C<new>. | |
67 | 157 |
180 | 158 Если является любым другим объектом или скаляром, то будет передан параметром методу |
159 C<new> как есть. | |
67 | 160 |
73 | 161 =item C<$method> |
162 | |
180 | 163 Имя метода (или ссылка на процедуру), который будет вызван у C<$factory> при создании |
164 текущей фабрикой нового объекта. | |
73 | 165 |
67 | 166 =back |
167 | |
168 =item C< [get] factory > | |
64 | 169 |
180 | 170 Свойство, содержащее фабрику для создание новых объектов текущей фабрикой. Чаще всего оно содержит |
171 имя класса. | |
64 | 172 |
67 | 173 =item C< [get] parameters > |
64 | 174 |
180 | 175 Свойство, содержит ссылку на параметры для создания объектов, при создании объекта эти параметры будут |
176 развернуты в список и переданы оператору C< new > фабрике из свойства C< factory >, за ними будут | |
177 следовать параметры непосредственно текущей фабрики. | |
67 | 178 |
181 | 179 =item C<MergeParameters(@params)> |
180 | |
181 Метод смешивающий фиксированные параметры с параметрами переданными методу C<new(@params)>. По умолчанию | |
182 добавляет пареметры фабрики в конец к фиксированным параметрам. Для изменения этого поведения требуется | |
183 переопределить данный метод. Также этот метод можно переопределить для передачи параметров, значения | |
184 которых вычисляются. | |
185 | |
67 | 186 =item C<new(@params)> |
187 | |
180 | 188 Создает новый объект, используя свйство C<factory> как фабрику и передавая туда параметры |
189 из свойства C<parameters> и списка C<@params>. Ниже приведен упрощенный пример, как это происходит. | |
67 | 190 |
191 =begin code | |
192 | |
193 sub new { | |
194 my ($this,@params) = @_; | |
195 | |
73 | 196 my $method = $this->method || 'new'; |
197 | |
198 return $this->factory->$method(_as_list($this->parameters), @params); | |
67 | 199 } |
200 | |
201 =end code | |
64 | 202 |
203 =back | |
204 | |
180 | 205 =cut |