libfactory++ FAQ
----------------

libfactory++ is (c) 2004 Martin F. Krafft <krafft@ailab.ch>
and distributed under the terms of the Artistic Licence.
See the file ./COPYING in the source distribution for more information.

Revision: $Id: FAQ,v 1.4 2004/06/01 09:45:28 krafft Exp $

Please send bugreports to <libfactory@pobox.madduck.net>

===============================================================================

1. There exist factories all over the place. For instance, Loki. Or the s11n
   class_loader. Why are you adding another one to the mess? What's different
   about libfactory++?

   None of the factory classes could do the one thing that caused me to start
   this library: control the actual construction of the object in a sensible
   way. The approach I took combines the various known creational patterns
   (see "Design Patterns", Gamma et al., 1995) into one intuitive interface.
   You can use a Builder to manage building of a specific object. You can use
   a Factory to make the object. Or you can use an AbstractFactory to decide
   at runtime what kind of object to create.
   
   That being the actual creation, libfactory++ also handles the task of
   construction nicely. You can create objects in three ways: by default, the
   object type's default constructor is used to initialise the object. You
   may, however, specify your own constructor. This is an instance of the
   Command design pattern. Last, but not least, you may have the object
   initialised from a Prototype of the same kind as the object.

   Neither Loki nor any other factory approach I saw can handle all these as
   cleanly as libfactory++. At least I think so. Loki does come close, but it
   contains a lot of other stuff, which, although quite amazing and definitely
   at the core of generic programming, does not lend itself to inclusion in
   other projects. Partly, that's due because Loki is largely unmaintained and
   was designed to serve as a demonstration for Alexandrescu's excellent book
   ("Modern C++ Design", Alexandrescu, 2001). I wish I had read that book
   before libfactory++. As it stands, I figured out all these things by
   myself <pat on the back...>.

   So libfactory++ was designed to be flexible and cool, and it's designed to
   be maintained and extended over the next years (until the new C++ standard
   is published, when it'll likely be unnecessary (or included)). Use it. If
   you don't like something, tell me. Or submit a patch directly. It would be
   good to talk to me before though.

===============================================================================

2. I provided a custom constructor for one of my types, derived from the
   standard constructor. I implemented the appropriate operator(), but when
   I pass the custom constructor as argument to a ConstructionRequest object,
   or directly to the Factory::create method, the default constructor is
   called. What's going on?

   The problem is one of const-ness. If your constructor is a const
   constructor -- that is, it changes the constructed object, but not
   itself -- then you can simply get around this problem by changing the
   your operator() to be a const member function. Thus, instead of writing:

     MyType* operator()(MyType* obj) { ... }

   you write

     MyType* operator()(MyType* obj) const { ... }

   If your constructor needs to change its internal state during the
   construction of an object, then you need to fix the way you are
   initialising the ConstructionRequest, or the way you are invoking
   Factory::create. In short, you need to pass an object, not a temporary
   reference. Doing something like:

     make_construction_request("AA", MyConstructor(42));

   creates a reference to a temporary MyConstructor object, which will be
   passed as a constant. If MyConstructor must be non-const, you have to first
   create a constructor object, the pass it into the function:

      MyConstructor my_constructor(42);
      make_construction_request("AA", my_constructor);

   The same applies if you are calling Factory::create directly.

   Until I find a better way to implement the constructor objects, you will
   have to live with this. It's not too bad anyway, forces you to understand
   what's going on :_)

===============================================================================

3. Why does the Factory template class provide a destroy() method? Do I have
   to use it?

   The short answer is: yes, you should.

   The medium answer is: you should, if you use a custom allocator. If you
   don't specify an allocator, you can safely call delete on the object the
   factory created. Nevertheless, when possible, use the factory method to
   destroy an object. This will allow you to retain the class's flexibility
   with respect to the creation policy. See the long answer...

   The long answer is: The factory does not impose an allocation method on
   you. In the default case, it uses new/delete to create objects in the
   system heap. However, due to performance issues, you may choose to replace
   this behaviour with a different policy, e.g. make the factory use a pool
   allocator instead of the new/delete allocator.

   Staying with the example of a pool allocator, the allocation of memory on
   the system heap is now done by the pool allocator. It allocates a larger
   number of bytes, and then hands out chunks of the larger pool to objects
   requesting space. Thus, the space occupied by any factory-generated object
   was never allocated by itself, and it does not belong to the object.

   If you call delete on the object when the occupied space is really just
   a chunk from an allocation pool, you program will likely crash -- the
   behaviour is undefined. The only entity that knows how to delete the object
   is the pool allocator, which may choose to recycle the space for another
   object, or simply flag it as used and deallocate it together with the whole
   pool at destruction of the allocator. Thus, you need to hand the object
   back to the allocator for destruction if you don't want to risk fatal
   program faults.

   See the next question for more information.

===============================================================================

4. Why do I have to pass the type of the object I create (its key, actually)
   to the destroy method (or the destruction request)? That seems awfully
   silly.

   Yes, yes it does. And I apologise. Currently, the design of the builders
   dictate this. After all, you can have a different allocator for every
   builder. Now, I know that this is far from reality, and that one custom
   allocator for a whole hierarchy is plenty and enough. Nevertheless, I had
   to implement libfactory++ to get it working. Now it has to be improved.
   I will ponder a redesign of the destruction as soon as I get more time to
   work on this. 
   
   Of course, suggestions and/or patches are gladly welcome. Please see the
   TODO file for some thoughts. I think I already know how to do it... by
   moving the allocation interface to the BuilderBase class. The other
   solution would be the consistent use of smart pointers. However, due to
   lack of experience with those, I have put that thought aside for now.
   I wonder if smart pointers would be too "high-level" for a generic,
   low-level library such as libfactory++.
   
===============================================================================
