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
268 that 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
357 of 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
395 for 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
399 "factory_log()" message is issued if the type has already been
400 registered.
401
402 remove_factory_type( @object_types )
403
404 Removes a factory type from the factory. This is the opposite of
405 "add_factory_type()". No return value.
406
407 Removing a factory type is useful if a subclass of the factory wants to
408 redefine the mapping for the factory type. "add_factory_type()" doesn't
409 allow overriding a factory type, so you have to remove it first.
410
411 unregister_factory_type( @object_types )
412
413 Unregisters a factory type from the factory. This is the opposite of
414 "register_factory_type()". No return value.
415
416 Unregistering a factory type is useful if a subclass of the factory
417 wants to redefine the mapping for the factory type.
418 "register_factory_type()" doesn't allow overriding a factory type, so
419 you have to unregister it first.
420
421 get_factory_type_for( $class )
422
423 Takes an object or a class name string and returns the factory type
424 that is used to construct that class. Returns undef if there is no such
425 factory type.
426
427 get_loaded_classes()
428
429 Returns a sorted list of the currently loaded classes. If no classes
430 have been loaded yet, returns an empty list.
431
432 get_loaded_types()
433
434 Returns a sorted list of the currently loaded types. If no classes have
435 been loaded yet, returns an empty list.
436
437 get_registered_classes()
438
439 Returns a sorted list of the classes that were ever registered. If no
440 classes have been registered yet, returns an empty list.
441
442 Note that a class can be both registered and loaded since we do not
443 clear out the registration once a registered class has been loaded on
444 demand.
445
446 get_registered_class( $factory_type )
447
448 Returns a registered class given a factory type. If no class of type
449 $factory_type is registered, returns undef. If no classes have been
450 registered yet, returns undef.
451
452 get_registered_types()
453
454 Returns a sorted list of the types that were ever registered. If no
455 types have been registered yet, returns an empty list.
456
457 Note that a type can be both registered and loaded since we do not
458 clear out the registration once a registered type has been loaded on
459 demand.
460
461 factory_log( @message )
462
463 Used internally instead of "warn" so subclasses can override. Default
464 implementation just uses "warn".
465
466 factory_error( @message )
467
468 Used internally instead of "die" so subclasses can override. Default
469 implementation just uses "die".
470
471 Implementation Methods
472 If your implementations -- objects the factory creates -- also inherit
473 from the factory they can do a little introspection and tell you where
474 they came from. (Inheriting from the factory is a common usage: the
475 SYNOPSIS example does it.)
476
477 All methods here can be called on either a class or an object.
478
479 get_my_factory()
480
481 Returns the factory class used to create this object or instances of
482 this class. If this class (or object class) hasn't been registered with
483 the factory it returns undef.
484
485 So with our SYNOPSIS example we could do:
486
487 my $custom_object = My::Factory->new( 'custom' );
488 print "Object was created by factory ",
489 "'", $custom_object->get_my_factory, "';
490
491 which would print:
492
493 Object was created by factory 'My::Factory'
494
495 get_my_factory_type()
496
497 Returns the type used to by the factory create this object or instances
498 of this class. If this class (or object class) hasn't been registered
499 with the factory it returns undef.
500
501 So with our SYNOPSIS example we could do:
502
503 my $custom_object = My::Factory->new( 'custom' );
504 print "Object is of type ",
505 "'", $custom_object->get_my_factory_type, "'";
506
507 which would print:
508
509 Object is of type 'custom'
510
512 Copyright (c) 2002-2007 Chris Winters. All rights reserved.
513
514 This library is free software; you can redistribute it and/or modify it
515 under the same terms as Perl itself.
516
518 "Design Patterns", by Erich Gamma, Richard Helm, Ralph Johnson and John
519 Vlissides. Addison Wesley Longman, 1995. Specifically, the 'Factory
520 Method' pattern, pp. 107-116.
521
523 Fred Moyer <fred@redhotpenguin.com> is the current maintainer.
524
525 Chris Winters <chris@cwinters.com>
526
527 Eric Andreychek <eric@openthought.net> implemented overridable
528 log/error capability and prodded the module into a simpler design.
529
530 Srdjan Jankovic <srdjan@catalyst.net.nz> contributed the idea for
531 'get_my_factory()' and 'get_my_factory_type()'
532
533 Sebastian Knapp <giftnuss@netscape.net> contributed the idea for
534 'get_registered_class()'
535
536 Marcel Gruenauer <marcel@cpan.org> contributed the methods
537 remove_factory_type() and unregister_factory_type().
538
539
540
541perl v5.32.0 2020-07-28 Class::Factory(3)