1Class::Factory(3) User Contributed Perl Documentation Class::Factory(3)
2
3
4
6 Class::Factory - Base class for dynamic factory classes
7
9 package My::Factory;
10 use base qw( Class::Factory );
11
12 # Add our default types
13
14 # This type is loaded when the statement is run
15
16 __PACKAGE__->add_factory_type( perl => 'My::Factory::Perl' );
17
18 # This type is loaded on the first request for type 'blech'
19
20 __PACKAGE__->register_factory_type( blech => 'My::Factory::Blech' );
21
22 1;
23
24 # Adding a new factory type in code -- 'Other::Custom::Class' is
25 # brought in via 'require' immediately
26
27 My::Factory->add_factory_type( custom => 'Other::Custom::Class' );
28 my $custom_object = My::Factory->new( 'custom', { this => 'that' } );
29
30 # Registering a new factory type in code; 'Other::Custom::ClassTwo'
31 # isn't brought in yet...
32
33 My::Factory->register_factory_type( custom_two => 'Other::Custom::ClassTwo' );
34
35 # ...it's only 'require'd when the first instance of the type is
36 # created
37
38 my $custom_object = My::Factory->new( 'custom_two', { this => 'that' } );
39
40 # Get all the loaded and registered classes and types
41
42 my @loaded_classes = My::Factory->get_loaded_classes;
43 my @loaded_types = My::Factory->get_loaded_types;
44 my @registered_classes = My::Factory->get_registered_classes;
45 my @registered_types = My::Factory->get_registered_types;
46
47 # Get a registered class by it's factory type
48
49 my $registered_class = My::Factory->get_registered_class( 'type' );
50
51 # Ask the object created by the factory: Where did I come from?
52
53 my $custom_object = My::Factory->new( 'custom' );
54 print "Object was created by factory: ",
55 $custom_object->get_my_factory, " ",
56 "and is of type: ",
57 $custom_object->get_my_factory_type;
58
59 # Remove a factory type
60
61 My::Factory->remove_factory_type('perl');
62
63 # Unregister a factory type
64
65 My::Factory->unregister_factory_type('blech');
66
68 This is a simple module that factory classes can use to generate new
69 types of objects on the fly, providing a consistent interface to common
70 groups of objects.
71
72 Factory classes are used when you have different implementations for
73 the same set of tasks but may not know in advance what implementations
74 you will be using. Configuration files are a good example of this.
75 There are four basic operations you would want to do with any
76 configuration: read the file in, lookup a value, set a value, write the
77 file out. There are also many different types of configuration files,
78 and you may want users to be able to provide an implementation for
79 their own home-grown configuration format.
80
81 With a factory class this is easy. To create the factory class, just
82 subclass "Class::Factory" and create an interface for your
83 configuration serializer. "Class::Factory" even provides a simple
84 constructor for you. Here's a sample interface and our two built-in
85 configuration types:
86
87 package My::ConfigFactory;
88
89 use strict;
90 use base qw( Class::Factory );
91
92 sub read { die "Define read() in implementation" }
93 sub write { die "Define write() in implementation" }
94 sub get { die "Define get() in implementation" }
95 sub set { die "Define set() in implementation" }
96
97 __PACKAGE__->add_factory_type( ini => 'My::IniReader' );
98 __PACKAGE__->add_factory_type( perl => 'My::PerlReader' );
99
100 1;
101
102 And then users can add their own subclasses:
103
104 package My::CustomConfig;
105
106 use strict;
107 use base qw( My::ConfigFactory );
108
109 sub init {
110 my ( $self, $filename, $params ) = @_;
111 if ( $params->{base_url} ) {
112 $self->read_from_web( join( '/', $params->{base_url}, $filename ) );
113 }
114 else {
115 $self->read( $filename );
116 }
117 return $self;
118 }
119
120 sub read { ... implementation to read a file ... }
121 sub write { ... implementation to write a file ... }
122 sub get { ... implementation to get a value ... }
123 sub set { ... implementation to set a value ... }
124
125 sub read_from_web { ... implementation to read via http ... }
126
127 # Now register my type with the factory
128
129 My::ConfigFactory->add_factory_type( 'mytype' => __PACKAGE__ );
130
131 1;
132
133 (You may not wish to make your factory the same as your interface, but
134 this is an abbreviated example.)
135
136 So now users can use the custom configuration with something like:
137
138 #!/usr/bin/perl
139
140 use strict;
141 use My::ConfigFactory;
142 use My::CustomConfig; # this adds the factory type 'custom'...
143
144 my $config = My::ConfigFactory->new( 'custom', 'myconf.dat' );
145 print "Configuration is a: ", ref( $config ), "\n";
146
147 Which prints:
148
149 Configuration is a My::CustomConfig
150
151 And they can even add their own:
152
153 My::ConfigFactory->register_factory_type( 'newtype' => 'My::New::ConfigReader' );
154
155 This might not seem like a very big win, and for small standalone
156 applications probably isn't. But when you develop large applications
157 the "(add|register)_factory_type()" step will almost certainly be done
158 at application initialization time, hidden away from the eyes of the
159 application developer. That developer will only know that she can
160 access the different object types as if they are part of the system.
161
162 As you see in the example above implementation for subclasses is very
163 simple -- just add "Class::Factory" to your inheritance tree and you
164 are done.
165
166 Gotchas
167 All type-to-class mapping information is stored under the original
168 subclass name. So the following will not do what you expect:
169
170 package My::Factory;
171 use base qw( Class::Factory );
172 ...
173
174 package My::Implementation;
175 use base qw( My::Factory );
176 ...
177 My::Implementation->register_factory_type( impl => 'My::Implementation' );
178
179 This does not register 'My::Implementation' under 'My::Factory' as you
180 would like, it registers the type under 'My::Implementation' because
181 that's the class we used to invoke the 'register_factory_type' method.
182 Make all add_factory_type() and register_factory_type() invocations
183 with the original factory class name and you'll be golden.
184
185 Registering Factory Types
186 As an additional feature, you can have your class accept registered
187 types that get brought in only when requested. This lazy loading
188 feature can be very useful when your factory offers many choices and
189 users will only need one or two of them at a time, or when some classes
190 the factory generates use libraries that some users may not have
191 installed.
192
193 For example, say I have a factory that generates an object which parses
194 GET/POST parameters. One type uses the ubiquitous CGI module, the other
195 uses the faster but rarer Apache::Request. Many systems do not have
196 Apache::Request installed so we do not want to 'use' the module
197 whenever we create the factory.
198
199 Instead, we will register these types with the factory and only when
200 that type is requested will we bring that implementation in. To extend
201 our configuration example above we'll change the configuration factory
202 to use register_factory_type() instead of add_factory_type():
203
204 package My::ConfigFactory;
205
206 use strict;
207 use base qw( Class::Factory );
208
209 sub read { die "Define read() in implementation" }
210 sub write { die "Define write() in implementation" }
211 sub get { die "Define get() in implementation" }
212 sub set { die "Define set() in implementation" }
213
214 __PACKAGE__->register_factory_type( ini => 'My::IniReader' );
215 __PACKAGE__->register_factory_type( perl => 'My::PerlReader' );
216
217 1;
218
219 This way you can leave the actual inclusion of the module for people
220 who would actually use it. For our configuration example we might have:
221
222 My::ConfigFactory->register_factory_type( SOAP => 'My::Config::SOAP' );
223
224 So the "My::Config::SOAP" class will only get included at the first
225 request for a configuration object of that type:
226
227 my $config = My::ConfigFactory->new( 'SOAP', 'http://myco.com/',
228 { port => 8080, ... } );
229
230 Subclassing
231 Piece of cake:
232
233 package My::Factory;
234 use base qw( Class::Factory );
235
236 or the old-school:
237
238 package My::Factory;
239 use Class::Factory;
240 @My::Factory::ISA = qw( Class::Factory );
241
242 You can also override two methods for logging/error handling. There are
243 a few instances where "Class::Factory" may generate a warning message,
244 or even a fatal error. Internally, these are handled using "warn" and
245 "die", respectively.
246
247 This may not always be what you want though. Maybe you have a
248 different logging facility you wish to use. Perhaps you have a more
249 sophisticated method of handling errors (like Log::Log4perl. If this
250 is the case, you are welcome to override either of these methods.
251
252 Currently, these two methods are implemented like the following:
253
254 sub factory_log { shift; warn @_, "\n" }
255 sub factory_error { shift; die @_, "\n" }
256
257 Assume that instead of using "warn", you wish to use Log::Log4perl.
258 So, in your subclass, you might override "factory_log" like so:
259
260 sub factory_log {
261 shift;
262 my $logger = get_logger;
263 $logger->warn( @_ );
264 }
265
266 Common Usage Pattern: Initializing from the constructor
267 This is a very common pattern: Subclasses create an init() method that
268 gets called when the object is created:
269
270 package My::Factory;
271
272 use strict;
273 use base qw( Class::Factory );
274
275 1;
276
277 And here is what a subclass might look like -- note that it doesn't
278 have to subclass "My::Factory" as our earlier examples did:
279
280 package My::Subclass;
281
282 use strict;
283 use base qw( Class::Accessor );
284
285 my @CONFIG_FIELDS = qw( status created_on created_by updated_on updated_by );
286 my @FIELDS = ( 'filename', @CONFIG_FIELDS );
287 My::Subclass->mk_accessors( @FIELDS );
288
289 # Note: we have taken the flattened C<@params> passed in and assigned
290 # the first element as C<$filename> and the other element as a
291 # hashref C<$params>
292
293 sub init {
294 my ( $self, $filename, $params ) = @_;
295 unless ( -f $filename ) {
296 die "Filename [$filename] does not exist. Object cannot be created";
297 }
298 $self->filename( filename );
299 $self->read_file_contents;
300 foreach my $field ( @CONFIG_FIELDS ) {
301 $self->{ $field } = $params->{ $field } if ( $params->{ $field } );
302 }
303 return $self;
304 }
305
306 The parent class ("My::Factory") has made as part of its definition
307 that the only parameters to be passed to the init() method are
308 $filename and $params, in that order. It could just as easily have
309 specified a single hashref parameter.
310
311 These sorts of specifications are informal and not enforced by this
312 "Class::Factory".
313
314 Registering Common Types by Default
315 Many times you will want the parent class to automatically register the
316 types it knows about:
317
318 package My::Factory;
319
320 use strict;
321 use base qw( Class::Factory );
322
323 My::Factory->register_factory_type( type1 => 'My::Impl::Type1' );
324 My::Factory->register_factory_type( type2 => 'My::Impl::Type2' );
325
326 1;
327
328 This allows the default types to be registered when the factory is
329 initialized. So you can use the default implementations without any
330 more registering/adding:
331
332 #!/usr/bin/perl
333
334 use strict;
335 use My::Factory;
336
337 my $impl1 = My::Factory->new( 'type1' );
338 my $impl2 = My::Factory->new( 'type2' );
339
341 Factory Methods
342 new( $type, @params )
343
344 This is a default constructor you can use. It is quite simple:
345
346 sub new {
347 my ( $pkg, $type, @params ) = @_;
348 my $class = $pkg->get_factory_class( $type );
349 return undef unless ( $class );
350 my $self = bless( {}, $class );
351 return $self->init( @params );
352 }
353
354 We just create a new object as a blessed hashref of the class
355 associated (from an earlier call to add_factory_type() or
356 register_factory_type()) with $type and then call the init() method of
357 that object. The init() method should return the object, or die on
358 error.
359
360 If we do not get a class name from get_factory_class() we issue a
361 factory_error() message which typically means we throw a "die".
362 However, if you've overridden factory_error() and do not die, this
363 factory call will return "undef".
364
365 get_factory_class( $object_type )
366
367 Usually called from a constructor when you want to lookup a class by a
368 type and create a new object of $object_type. If $object_type is
369 associated with a class and that class has already been included, the
370 class is returned. If $object_type is registered with a class (not yet
371 included), then we try to "require" the class. Any errors on the
372 "require" bubble up to the caller. If there are no errors, the class is
373 returned.
374
375 Returns: name of class. If a class matching $object_type is not found
376 or cannot be "require"d, then a die() (or more specifically, a
377 factory_error()) is thrown.
378
379 add_factory_type( $object_type, $object_class )
380
381 Tells the factory to dynamically add a new type to its stable and
382 brings in the class implementing that type using "require". After
383 running this the factory class will be able to create new objects of
384 type $object_type.
385
386 Returns: name of class added if successful. If the proper parameters
387 are not given or if we cannot find $object_class in @INC, then we call
388 factory_error(). A factory_log() message is issued if the type has
389 already been added.
390
391 register_factory_type( $object_type, $object_class )
392
393 Tells the factory to register a new factory type. This type will be
394 dynamically included (using add_factory_type() at the first request for
395 an instance of that type.
396
397 Returns: name of class registered if successful. If the proper
398 parameters are not given then we call factory_error(). A factory_log()
399 message is issued if the type has already been registered.
400
401 remove_factory_type( @object_types )
402
403 Removes a factory type from the factory. This is the opposite of
404 add_factory_type(). No return value.
405
406 Removing a factory type is useful if a subclass of the factory wants to
407 redefine the mapping for the factory type. add_factory_type() doesn't
408 allow overriding a factory type, so you have to remove it first.
409
410 unregister_factory_type( @object_types )
411
412 Unregisters a factory type from the factory. This is the opposite of
413 register_factory_type(). No return value.
414
415 Unregistering a factory type is useful if a subclass of the factory
416 wants to redefine the mapping for the factory type.
417 register_factory_type() doesn't allow overriding a factory type, so you
418 have to unregister it first.
419
420 get_factory_type_for( $class )
421
422 Takes an object or a class name string and returns the factory type
423 that is used to construct that class. Returns undef if there is no such
424 factory type.
425
426 get_loaded_classes()
427
428 Returns a sorted list of the currently loaded classes. If no classes
429 have been loaded yet, returns an empty list.
430
431 get_loaded_types()
432
433 Returns a sorted list of the currently loaded types. If no classes have
434 been loaded yet, returns an empty list.
435
436 get_registered_classes()
437
438 Returns a sorted list of the classes that were ever registered. If no
439 classes have been registered yet, returns an empty list.
440
441 Note that a class can be both registered and loaded since we do not
442 clear out the registration once a registered class has been loaded on
443 demand.
444
445 get_registered_class( $factory_type )
446
447 Returns a registered class given a factory type. If no class of type
448 $factory_type is registered, returns undef. If no classes have been
449 registered yet, returns undef.
450
451 get_registered_types()
452
453 Returns a sorted list of the types that were ever registered. If no
454 types have been registered yet, returns an empty list.
455
456 Note that a type can be both registered and loaded since we do not
457 clear out the registration once a registered type has been loaded on
458 demand.
459
460 factory_log( @message )
461
462 Used internally instead of "warn" so subclasses can override. Default
463 implementation just uses "warn".
464
465 factory_error( @message )
466
467 Used internally instead of "die" so subclasses can override. Default
468 implementation just uses "die".
469
470 Implementation Methods
471 If your implementations -- objects the factory creates -- also inherit
472 from the factory they can do a little introspection and tell you where
473 they came from. (Inheriting from the factory is a common usage: the
474 SYNOPSIS example does it.)
475
476 All methods here can be called on either a class or an object.
477
478 get_my_factory()
479
480 Returns the factory class used to create this object or instances of
481 this class. If this class (or object class) hasn't been registered with
482 the factory it returns undef.
483
484 So with our SYNOPSIS example we could do:
485
486 my $custom_object = My::Factory->new( 'custom' );
487 print "Object was created by factory ",
488 "'", $custom_object->get_my_factory, "';
489
490 which would print:
491
492 Object was created by factory 'My::Factory'
493
494 get_my_factory_type()
495
496 Returns the type used to by the factory create this object or instances
497 of this class. If this class (or object class) hasn't been registered
498 with the factory it returns undef.
499
500 So with our SYNOPSIS example we could do:
501
502 my $custom_object = My::Factory->new( 'custom' );
503 print "Object is of type ",
504 "'", $custom_object->get_my_factory_type, "'";
505
506 which would print:
507
508 Object is of type 'custom'
509
511 Copyright (c) 2002-2007 Chris Winters. All rights reserved.
512
513 This library is free software; you can redistribute it and/or modify it
514 under the same terms as Perl itself.
515
517 "Design Patterns", by Erich Gamma, Richard Helm, Ralph Johnson and John
518 Vlissides. Addison Wesley Longman, 1995. Specifically, the 'Factory
519 Method' pattern, pp. 107-116.
520
522 Fred Moyer <fred@redhotpenguin.com> is the current maintainer.
523
524 Chris Winters <chris@cwinters.com>
525
526 Eric Andreychek <eric@openthought.net> implemented overridable
527 log/error capability and prodded the module into a simpler design.
528
529 Srdjan Jankovic <srdjan@catalyst.net.nz> contributed the idea for
530 'get_my_factory()' and 'get_my_factory_type()'
531
532 Sebastian Knapp <giftnuss@netscape.net> contributed the idea for
533 'get_registered_class()'
534
535 Marcel Gruenauer <marcel@cpan.org> contributed the methods
536 remove_factory_type() and unregister_factory_type().
537
538
539
540perl v5.36.0 2023-01-20 Class::Factory(3)