Mercurial > pub > Impl
annotate Lib/IMPL/Object/Factory.pm @ 187:927653d01f4f
TTControl::AUTOLOAD now accesses nodeProperties
Added TTControl::renderBlock property to access RENDER block of the template
| author | sergey |
|---|---|
| date | Tue, 03 Apr 2012 07:54:25 +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 |
