Mercurial > pub > Impl
annotate Lib/IMPL/Object/Factory.pm @ 170:b88b7fe60aa3
refactoring
author | sourcer |
---|---|
date | Tue, 24 May 2011 01:11:16 +0400 |
parents | 4267a2ac3d46 |
children | d1676be8afcc |
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 |
6 use IMPL::Class::Property; | |
7 | |
8 BEGIN { | |
9 public property factory => prop_get | owner_set; | |
73 | 10 public property parameters => prop_get | owner_set; |
11 public property method => prop_get | owner_set; | |
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) { | |
91 | 36 $surrogate->callCTOR($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) { |
47 $this->factory->$method($this->parameters ? (_as_list($this->parameters),@_) : @_); | |
48 } else { | |
49 $this->factory->new($this->parameters ? (_as_list($this->parameters),@_) : @_); | |
50 } | |
64 | 51 } |
52 | |
53 sub _as_list { | |
54 ref $_[0] ? | |
55 (ref $_[0] eq 'HASH' ? | |
56 %{$_[0]} | |
57 : | |
58 (ref $_[0] eq 'ARRAY'? | |
59 @{$_[0]} | |
60 : | |
61 $_[0] | |
62 ) | |
63 ) | |
64 : | |
65 ($_[0]); | |
66 } | |
67 | |
68 | |
69 1; | |
70 | |
71 __END__ | |
72 | |
73 =pod | |
74 | |
75 =head1 SYNOPSIS | |
76 | |
77 =begin code | |
78 | |
79 my $factory = new IMPL::Object::Factory( | |
80 'MyApp::User', | |
81 { | |
82 isAdmin => 1 | |
83 } | |
84 ); | |
85 | |
67 | 86 my $class = 'MyApp::User'; |
87 | |
88 my $user; | |
89 | |
90 $user = $class->new(name => 'nobody'); # will create object MyApp::User | |
91 # and pass parameters (name=>'nobody') | |
92 | |
93 $user = $factory->new(name => 'root'); # will create object MyApp::User | |
94 # and pass paremeters (isAdmin => 1, name => 'root') | |
95 | |
64 | 96 =end code |
97 | |
67 | 98 Или сериализованная форма в XML. |
99 | |
100 =begin code xml | |
64 | 101 |
67 | 102 <factory type="IMPL::Object::Factory"> |
103 <factory>MyApp::User</factory>, | |
104 <parameters type="HASH"> | |
105 <isAdmin>1</isAdmin> | |
106 </parameters> | |
107 </factory> | |
108 | |
109 =end code xml | |
64 | 110 |
111 =head1 DESCRIPTION | |
112 | |
67 | 113 C<[Serializable]> |
114 | |
64 | 115 Класс, реализующий фабрику классов. |
116 | |
117 Фабрика классов это любой объект, который имеет метод C< new > вызов которого приводит к созданию нового | |
118 объекта. Например каждый класс сам явялется фабрикой, поскольку, если у него вызвать метод | |
119 C< new >, то будет создан объект. Полученные объекты, в силу механизмов языка Perl, также | |
120 являются фабриками, притом такимиже, что и класс. | |
121 | |
122 Данный класс меняет поведение метода C< new > в зависимости от контекста вызова: статического | |
123 метода или метода объекта. При вызове метода C< new > у класса происходит создание объекта | |
124 фабрики с определенными параметрами. Далее объект-фабрика может быть использована для создания | |
125 объектов уже на основе параметров фабрики. | |
126 | |
127 =head1 MEMBERS | |
128 | |
129 =over | |
130 | |
73 | 131 =item C< CTOR($factory,$parameters,$method) > |
67 | 132 |
73 | 133 Создает новый экземпляр фабрики. |
67 | 134 |
135 =over | |
136 | |
137 =item C<$factory> | |
138 | |
139 Либо имя класса, либо другая фабрика. | |
140 | |
141 =item C<$parameters> | |
142 | |
143 Ссылка на параметры для создания объектов, может быть ссылкой на хеш, массив и т.д. | |
144 | |
145 Если является ссылкой на хеш, то при создании объектов данной фабрикой этот хеш | |
146 будет развернут в список и передан параметрами методу C<new>. | |
147 | |
148 Если является ссылкой на массив, то при создании объектов данной фабрикой этот массив | |
149 будет передан в списк и передан параметрами методу C<new>. | |
150 | |
151 Если является любым другим объектом или скаляром, то будет передан параметром методу | |
152 C<new> как есть. | |
153 | |
73 | 154 =item C<$method> |
155 | |
156 Имя метода (или ссылка на процедуру), который будет вызван у C<$factory> при создании | |
157 текущей фабрикой нового объекта. | |
158 | |
67 | 159 =back |
160 | |
161 =item C< [get] factory > | |
64 | 162 |
163 Свойство, содержащее фабрику для создание новых объектов текущей фабрикой. Чаще всего оно содержит | |
164 имя класса. | |
165 | |
67 | 166 =item C< [get] parameters > |
64 | 167 |
168 Свойство, содержит ссылку на параметры для создания объектов, при создании объекта эти параметры будут | |
169 развернуты в список и переданы оператору C< new > фабрике из свойства C< factory >, за ними будут | |
67 | 170 следовать параметры непосредственно текущей фабрики. |
171 | |
172 =item C<new(@params)> | |
173 | |
174 Создает новый объект, используя свйство C<factory> как фабрику и передавая туда параметры | |
175 из свойства C<parameters> и списка C<@params>. Ниже приведен упрощенный пример, как это происходит. | |
176 | |
177 =begin code | |
178 | |
179 sub new { | |
180 my ($this,@params) = @_; | |
181 | |
73 | 182 my $method = $this->method || 'new'; |
183 | |
184 return $this->factory->$method(_as_list($this->parameters), @params); | |
67 | 185 } |
186 | |
187 =end code | |
64 | 188 |
189 =back | |
190 | |
191 =cut |