Click here to Skip to main content
Click here to Skip to main content

Different ways of implementing factories

By , 26 Mar 2003
 

Introduction

Sometimes you need to create instances of classes in parts of an application where you don't really need to know what the class details are. You just want to create an instance.
This is often solved by using factories. Constructions (in most cases these are classes) that have the single purpose of simply creating other instances. This article presents some different alternatives for writing such factories. Each with their own advantages and disadvantages.

Factory 1: the simple factory

Example 1 contains a simple factory class.
class SimpleClassFactory
   {
   public:
      SimpleClass *createInstance() {return new SimpleClass;}
   };
This class simply creates an instance of another class. This approach can be used if the number of different classes is limited. You then only need to write a limited number of class factories. The disadvantage of this approach is that if you have many different classes, that you need to write many factory classes as well. The following alternative tries to solve this.

Factory 2: the multi-factory

Example 2 contains a factory that is able to create different kinds of instances, depending on the given arguments. Suppose that we have the following class hierarchy:
class SimpleBaseClass
   {
   public:
      virtual int  getValue()          = 0;
      virtual void setValue(int value) = 0;
   };

class SimpleClass1 : public SimpleBaseClass
   {
   public:
      int  getValue()          {return m_value;}
      void setValue(int value) {m_value = value;}
   private:
      int m_value;
   };

class SimpleClass2 : public SimpleBaseClass
   {
   public:
      int  getValue()          {return m_value*100;}
      void setValue(int value) {m_value = value;}
   private:
      int m_value;
   };
A multi-factory implementation might look like this:
class SimpleClassFactory
   {
   public:
      SimpleBaseClass *createInstance1() {return new SimpleClass1;}
      SimpleBaseClass *createInstance2() {return new SimpleClass2;}
   };
This approach can be used if you have a central point that knows about all the different classes that need to be instantiated, and the caller of the factory knows which class he wants to instantiate. This multi-factory cannot be used if the caller of the factory does now know which classes could be generated by the factory and only passes some magic value that needs to be dispatched to the correct instantiation.

Factory 3: the dispatching multi-factory

This approach is very similar to the previous one, but uses a dispatching method.
class SimpleClassFactory
   {
   public:
      SimpleBaseClass *createInstance(int type);
   };

SimpleBaseClass *SimpleClassFactory::createInstance (int type)
{
if      (type==1) return new SimpleClass1;
else if (type==2) return new SimpleClass2;
else              return NULL;
}
If one needs to create an instance of a certain type (1 or 2), it can create the instance like this:
SimpleBaseClass    *simpleInstance     = NULL;
SimpleClassFactory  simpleClassFactory;
simpleInstance = simpleClassFactory.createInstance(1);
I admit that this is only a small difference with approach 2, but it can be useful in some situations.

Factory 4: the function-pointer-factory

The multi-factory has the disadvantage that the factory class needs to know about all the different classes. It cannot be used in the following situation:

Suppose that we have 10 classes. 5 of them are part of a module that is used in multiple applications. 5 of them are application-specific. They all inherit from the same base class. In some part of the application we need to create an instance of one of these classes. The exact class that needs to be instantiated depends on given value.

  • We cannot write the factory in the shared part since it only knows about 5 of the classes.
  • We don't want to write the factory in the application specific part since that requires us to copy it over multiple applications AND it can cause problems if a 6th shared class is added to the shared module (some applications might forget to add it to the application-specific-factory).
We could solve this problem by using function pointers, like this:
class SimpleClass1 : public SimpleBaseClass
   {
   public:
      int  getValue()          {return m_value;}
      void setValue(int value) {m_value = value;}
      static SimpleBaseClass *createInstance() {return new SimpleClass1;}
   private:
      int m_value;
   };
class SimpleClass2 : public SimpleBaseClass
   {
   public:
      int  getValue()          {return m_value*100;}
      void setValue(int value) {m_value = value;}
      static SimpleBaseClass *createInstance() {return new SimpleClass2;}
   private:
      int m_value;
   };
Each class is given a static 'createInstance()' method that creates an instance of the class. Our method that needs to create an instance based on a given value, might look like this:
SimpleBaseClass *someMethod (
  std::map<int,FactoryFunction> factoryFunctions, int type)
{
return factoryFunctions[type]();
}
The application can feed it with the supported factories like this:
std::map<int,FactoryFunction>  factoryFunctions;
factoryFunctions[1] = &SimpleClass1::createInstance;
factoryFunctions[2] = &SimpleClass2::createInstance;
The method is then called like this:
simpleInstance = someMethod (factoryFunctions,1);
The advantage is that it is simple to use and that it doesn't require a factory per class or one big dispatching multi-factory that needs to know about all the classes. Also the solution seems understandable for developers with a pure C background. However, passing function pointers in C++ is sometimes regarded as 'not done', and in the following alternatives I'll give some other approaches.

Factory 5: the clone-factory

The clone factory approach makes use of 'dummy' instances that are cloned. We need to give each class that needs to be instantiated by someone a clone method, like this:
class SimpleBaseClass
   {
   public:
      virtual int              getValue()          = 0;
      virtual void             setValue(int value) = 0;
      virtual SimpleBaseClass *clone()             = 0;
   };

class SimpleClass1 : public SimpleBaseClass
   {
   public:
      int  getValue()          {return m_value;}
      void setValue(int value) {m_value = value;}
      SimpleBaseClass *clone() {return new SimpleClass1(*this);}
   private:
      int m_value;
   };

class SimpleClass2 : public SimpleBaseClass
   {
   public:
      int  getValue()          {return m_value*100;}
      void setValue(int value) {m_value = value;}
      SimpleBaseClass *clone() {return new SimpleClass2(*this);}
   private:
      int m_value;
   };
The method that needs to create the instances then needs a map of these 'dummy' instances instead of function pointers:
SimpleBaseClass *someMethod (
  std::map<int,SimpleBaseClass *> clonables, int type)
{
return clonables[type]->clone();
}
And using it works like this:
SimpleBaseClass                 *simpleInstance     = NULL;
SimpleClass1                     clonable1;
SimpleClass2                     clonable2;
std::map<int,SimpleBaseClass *>  clonables;

clonables[1] = &clonable1;
clonables[2] = &clonable2;

simpleInstance = someMethod (clonables,1);
The advantage of this approach is that we got rid of the function pointers. However, the price we have to pay is that we need those dummy instances. If the classes that need to be instantiated are simple (and don't use excessive memory) that might be a solution. In other situations where the class instances need lots of memory, or represent more physical things (files, sockets, ...) it can be annoying to have these dummy instances.

Factory 6: the template-factory

With this approach we try to write our factory using templates. First we foresee the following two template classes:
template <class BT>
class FactoryPlant
   {
   public:
      FactoryPlant() {}
      virtual ~FactoryPlant() {}
      virtual BT *createInstance() = 0;
   };

template <class BT,class ST>
class Factory : public FactoryPlant<BT>
   {
   public:
      Factory() {}
      virtual ~Factory() {}
      virtual BT *createInstance() {return new ST;}
   };
The FactoryPlant class is the super class for the actual factories. In our previous examples, all the classes that could be instantiated, all derived frm the same base class. This is logical because otherwise it would be impossible to write a 'generic' factory for these classes. The type given to the FactoryPlant is the base class of the instances that will be created by the factories inheriting from this FactoryPlant. The Factory class is given two types: the base class and the actual class that is instantiated.
As you can see the FactoryPlant base class already contains the pure virtual createInstance method. The Factory class implements the method, since it knows which sub class type is actually instantiated. We can now give our classes their own factory like this:
class SimpleClass1 : public SimpleBaseClass
   {
   public:
      int  getValue()          {return m_value;}
      void setValue(int value) {m_value = value;}
      static Factory<SimpleBaseClass,SimpleClass1> myFactory;
   private:
      int m_value;
   };
Factory<SimpleBaseClass,SimpleClass1> SimpleClass1::myFactory;

class SimpleClass2 : public SimpleBaseClass
   {
   public:
      int  getValue()          {return m_value*100;}
      void setValue(int value) {m_value = value;}
      static Factory<SimpleBaseClass,SimpleClass2> myFactory;
   private:
      int m_value;
   };
Factory<SimpleBaseClass,SimpleClass2> SimpleClass2::myFactory;
Instead of a function pointer, the class has a static factory instance. Notice that, since it is static, that we need to define it outside the class as well. Otherwise we will have unresolved externals. To simplify the use of types, we also added a type definition to our base class:
class SimpleBaseClass
   {
   public:
      virtual int              getValue()          = 0;
      virtual void             setValue(int value) = 0;
      typedef FactoryPlant<SimpleBaseClass> SimpleBaseClassFactory;
   };
Our method that needs to create instances of each of these classes, based on the magic number, now looks like this:
SimpleBaseClass *someMethod (
  std::map<int,SimpleBaseClass::SimpleBaseClassFactory *> factories, 
  int type)
{
return factories[type]->createInstance();
}
It is passed a map of factories (all deriving from SimpleBaseClass::SimpleBaseClassFactory, which is actually FactoryPlant<SimpleBaseClass>), and it calls the createInstance of the factory (depending on the given magic number). The application can now call this like this:
SimpleBaseClass     *simpleInstance     = NULL;
std::map<int,SimpleBaseClass::SimpleBaseClassFactory *>  factories;

factories[1] = &SimpleClass1::myFactory;
factories[2] = &SimpleClass2::myFactory;

simpleInstance = someMethod (factories,1);
In this example the build-up of the factories map is kept quite simple. In more complex situations part of the map could be created by a shared module. The application that simply needs to add his own factories (it wants to support) to the map.

Conclusion

There are many different methods of writing factories. I presented 6 of them here, each with their own advantages and disadvantages. In my situation (the reason I wrote this article), I actually needed the last one. I could use the function-pointer approach but using C-style-function pointers did not look like good C++ to me. I wasn't really fond of the clone-alternative either, so I started experimenting with the template approach. I hope this article might give you some ideas, and if you have some more ideas on writing factories, just send me a mail.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Patje
Software Developer
Belgium Belgium
Member

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralAuto Registrationmemberbyaxiom4 Jan '10 - 18:32 
Is it possible to adapt this code for auto registration, so that it is no longer necessary to register all of the classes in the main() function?
GeneralRe: Auto RegistrationmemberPatje4 Jan '10 - 21:38 
Yes,
you could do that quite easily.
What you would typically do is make a class (which can be the specific factory class itself) in which the constructor registers itself in a global singleton registry.
 
For example in the 'template factory' situation (case 6), you could add the 'key' (that is used to decide which factory to call to create the instance), as argument to the template class, and let the templated factory register itself in a global singleton registry.
The implementation of the template would then become something like this:
 
template <class BT>
class FactoryPlant
   {
   public:
      FactoryPlant(integer key) {globalRegistry.register(key,this);}
      virtual ~FactoryPlant() {}
      virtual BT *createInstance() = 0;
   };
 
template <class BT,class ST,integer key>
class Factory : public FactoryPlant <BT>
   {
   public:
      Factory() : FactoryPlan(key) {}
      virtual ~Factory() {}
      virtual BT *createInstance() {return new ST;}
   };
 
And the class could instantiate the factory like this:
 
class SimpleClass1 : public SimpleBaseClass
   {
   public:
      int  getValue()          {return m_value;}
      void setValue(int value) {m_value = value;}
      typedef Factory<SimpleBaseClass,SimpleClass1,1> MyFactory;
      static MyFactory myFactory;
   private:
      int m_value;
   };
SimpleClass1::MyFactory SimpleClass1::myFactory;
 
Since the data member 'myFactory' is defined statically in the class, it will be instantiated at startup of the application.
This will cause the Factory class to be instantiated with the two given types (SimpleBaseClass and SimpleClass1, and the given key value, which is 1 for SimpleClass1).
This will then cause the constructor of FactoryPlant to be called, which will register itself with the given key value.
 
Now all that's left is write the implementation of the GlobalRegistry, but this is quite straightforward: just keep a map that maps the key values to pointers to the factories.
 
In the given examples I've used an integer as key value. In practice you will often use a string (std::string) or something like a GUID to distinguish the different classes and factories in your application.
 
Enjoy life, this is not a rehearsal !!!


GeneralRe: Auto Registrationmemberbyaxiom7 Jan '10 - 19:52 
Thank you very much, Patje! Your article is like nothing else on the web. The information you've provided has helped me immensely and is very much appreciated.
 
I found an interesting paper through wikipedia about class factory auto registration.
 
Here is the wikipedia article: http://en.wikipedia.org/wiki/Abstract_factory_pattern
And here is a link to the paper: http://kent.dl.sourceforge.net/sourceforge/papafactory/PapaFactory-9.06.pdf
 

I took the C Macro (sometimes called "X Macro") approach to simplify the redundancy.
 
#define CREATE_CLASS( m_classname, m_baseclass ) \
	static m_baseclass * CreateItem( void ) \
{ \
	return new m_classname; \
}
 
#define MAKE_CLASS( m_classname ) \
class CreatorFuncUNIQE##m_classname { \
public: \
	CreatorFuncUNIQE##m_classname( ) { \
	CFactory.Register( &##m_classname::CreateShape, #m_classname ); \
	printf( "Creating CreatorFuncUNIQE%s.... sizeof: %i\n", #m_classname, sizeof( CreatorFuncUNIQE##m_classname ) ); \
} \
	~CreatorFuncUNIQE##m_classname() { \
	printf( "Destroying CreatorFunc%s...\n", #m_classname ); } \
} GlobalandstatictomCreatorFuncUNIQE##m_classname
 
I will be the first to admit that the code looks ugly and it is a big programming no-no. However, I have seen this kind of macro (X macro) code before in professional projects. I should also point out that, in places where I have seen macro laden code, it is almost always commented with regret and a desire to switch to a C++ template design.
 
Thanks again for your article!
Generalwhy someMethod, simpleInstancemembermauree21 Oct '07 - 5:35 
I'm confused on why we need the someMethod and simpleInstance.
Why can't I just do:
 
factoryFunctions[1]->setValue (123);
factoryFunctions[2]->setValue (123);
 
thanks (sorry for the newbie question)

AnswerRe: why someMethod, simpleInstancememberPatje21 Oct '07 - 18:23 
I assume you are talking about the last alternative.
 
The idea behind factories is to split the instances and their creation, so that you can create instances without really known from which [inherited] class they are.
In the last code sample, the factoryFunctions vector contains pointers to classes that are factory classes, not the classes which you want to create. The factory classes only have a method to create the instance, not the setValue and getValue of the other classes.
The someMethod function (which is not a very good name, I know), just creates the instance and returns it. In my example it was stored in simpleInstance so it can be manipulated further.
 
This means you could have this:
simpleInstance = someMethod (factories,1);
simpleInstance->setValue(123);

 
You could also do this:
simpleInstance = factories[1]->createInstance();
simpleInstance->setValue(123);

But I like to hide implementation details like createInstance and the map, therefore I made the someMethod function.
 
Note that the following compiles:
someMethod(factories,1)->setValue(123);

But it makes no sense, since someMethod creates the instance, returns it, and then the setValue is called on it, but your created instance is stored nowhere. So this creates a memory leak.
(although this could make sense in specific situations with the addition of cache that keeps the created instances).
 
Patje
 
Enjoy life, this is not a rehearsal !!!


Questionplease explain line of code in factory_4.cppmemberMelFenn20 Jul '07 - 2:38 
Could you please explain the following line of code in factory_4.cpp:
 
typedef SimpleBaseClass *(*FactoryFunction)();
 
Specifically explain the "*(*FactoryFunction)() " section. I've never seen this syntax before and also asked some others about it and we were all confused by it. Code does compile and run so valid but just don't understand it.
Thanks, MelFenn
AnswerRe: please explain line of code in factory_4.cppmemberPatje20 Jul '07 - 5:39 
This line declares FactoryFunction as a pointer to a function that returns a pointer to a SImpleBaseClass.
 
Try reading this page: http://www.ericgiguere.com/articles/reading-c-declarations.html[^] for an explanation on how to read C declarations (or just google for "reading C declarations").
 
There are even small utilities that can translate a declaration to plain English (google on "cdecl").
 
One of my favorites I once used (when still using plain C) was this one:
 
double (*(FunctionFactory(char *name)))(double);
 
FunctionFactory is a function with a string (char *) as argument, which returns a pointer to a function that takes a double as argument and returns a double.
The function had an implementation something like this (cannot remember it exactly):
 
if (!strcmp(name,"sin")) return &sin;
if (!strcmp(name,"cos")) return &cos;
 
and so on.
 
Hope this helps.
Have fun with it.
Patrick.
 
Enjoy life, this is not a rehearsal !!!


Questionsmall error?membercboles12 Apr '06 - 13:30 
At least in VC++ 7.1, I needed to make the following change to have things compile properly in the template example:
 
class Factory : public FactoryPlant

 
should be
 
class Factory : public FactoryPlant<BT>

GeneralHere is my template solution.memberphalanger6 Mar '03 - 20:19 
#include <map>
#include <functional>
#include <exception>
#include <stdexcept>
 
#include <memory>
#include <iostream>
 
template<class TSrcType>
class TypeID : public std::unary_function<TSrcType,TSrcType>
{
public:
     typedef TSrcType     objTypeId;
};
 
template<class TKeyType,class TBaseType>
class TObjFactory
{
public:
     typedef TBaseType *          value_type;
 
     TObjFactory(void) {}
     ~TObjFactory(void)
     {
          typeMapKeyToBuilder::iterator it(m_mapKeyToBuilder.begin()),itend(m_mapKeyToBuilder.end());
          for(;it != itend; ++it)
               delete it->second;
     }
 
     template<typename TSubType>
          void     registerBuilder(const TKeyType & key,TypeID<TSubType> obj)
          {
               typedef TypeID<TSubType>::objTypeId     srcType;
               typeMapKeyToBuilder::iterator it = m_mapKeyToBuilder.find(key);
               if (it != m_mapKeyToBuilder.end())
                    throw std::runtime_error("duplicate");
               m_mapKeyToBuilder[key] = new TObjBuilder<srcType>();
          }
 
     value_type     buildObj(const TKeyType & key)
     {
          typeMapKeyToBuilder::iterator it = m_mapKeyToBuilder.find(key);
          if (it == m_mapKeyToBuilder.end())
               throw std::runtime_error("not found");
          return it->second->buildObject();
     }
protected:
     class TObjBuilderBase
     {
     public:
          virtual value_type     buildObject(void) = 0;
     };
 
     template<class TSubType>
     class TObjBuilder : public TObjBuilderBase
     {
     public:
          virtual value_type     buildObject(void)
               {     return new TSubType();     }
     };
 
     typedef TObjBuilderBase *                         typeBuilderPtr;
     typedef std::map<TKeyType,typeBuilderPtr>     typeMapKeyToBuilder;
     typeMapKeyToBuilder          m_mapKeyToBuilder;
};
 
//---test---------------------
 
class Base
{
public:
     virtual void test(void) = 0;
};
 
class classA : public Base
{
public:
     virtual void test(void) { std::cout << 'A' << std::endl; }
};
 
class classB : public Base
{
public:
     virtual void test(void) { std::cout << 'B' << std::endl; }
};
 
int main(void)
{
     TObjFactory<int,Base>     myFactory;
     myFactory.registerBuilder(0,TypeID<classA>());
     myFactory.registerBuilder(1,TypeID<classB>());
 
     std::auto_ptr<Base> auA(myFactory.buildObj(0));
     std::auto_ptr<Base> auB(myFactory.buildObj(1));
 
     auA->test();
     auB->test();
    
     return 0;
}

GeneralRe: Here is my template solution.memberPatje6 Mar '03 - 20:24 
Thanks for your alternative, it looks like a promising one.
If I have more time (alas not today) I will dive into your code and study it deeply.
Would you mind if I add your solution to the article ?
Of course I'll mention you as the writer of that alternative.
Thanks.
 
Enjoy life, this is not a rehearsal !!!
 
My Articles:
- Implementing a Subject/Observer pattern with templates
- Different ways of writing class factories



GeneralRe: Here is my template solution.memberphalanger6 Mar '03 - 20:41 
Of course you can.
It's my pleasure.
Smile | :)
GeneralRe: Here is my template solution.memberdacrawford24 May '05 - 13:19 
Works great -- just what I was looking for. However, with the newest gcc versions, the warning, "implicit typename is deprecated" appears on lines 25, 33, 34, and 42.
 
adding typename as follows fixes it:
 
        typename typeMapKeyToBuilder::iterator it(m_mapKeyToBuilder.begin()),itend(m_mapKeyToBuilder.end());
        for(;it != itend; ++it)
            delete it->second;
    }
 
    template<typename TSubType>
        void    registerBuilder(const TKeyType & key,TypeID<TSubType> obj)
        {
            typedef typename TypeID<TSubType>::objTypeId    srcType;
            typename typeMapKeyToBuilder::iterator it = m_mapKeyToBuilder.find(key);
            if (it != m_mapKeyToBuilder.end())
                throw std::runtime_error("duplicate");
            m_mapKeyToBuilder[key] = new TObjBuilder<srcType>();
        }
 
    value_type    buildObj(const TKeyType & key)
    {
        typename typeMapKeyToBuilder::iterator it = m_mapKeyToBuilder.find(key);
 
 
Information about the warning was found at tim's journal: implicit typename is deprecated.
 
DAC
GeneralRe: Here is my template solution.memberebtrexler9 Feb '11 - 5:53 
Hi,
 
this is great code. I have tested it on VC++ 2010 and Borland RAD Studio 2010.
 
I have a question -- how would you implement a factory for a class that could not have a default contructor, but initialization parameters were necessary? I suppose you could just create a Base::Initialize(params...) function, but is there an elegant way with the templated method you show (phalanger)?
 
Thanks,
Brady
GeneralRe: Here is my template solution.memberPatje9 Feb '11 - 19:56 
If the constructor of one of your classes expects parameters, then there are two possibilities: either all of your classes made by the factory have the same arguments (and the caller of the factory will probably have to pass them to the factory), or only that specific class needs the arguments.
 
If all of the classes have different arguments, then the templated solution will be difficult to implement. You are actually forced to have constructors with identical signatures.
 
If all of the classes have the same arguments, you can simply pass all the arguments to the factories createInstance method, which will then pass it to the constructor. This can be easily put in the templated solution.
 
An alternative approach could be to use a separate configuration class. Instead of passing the initialization arguments one by one, define a configuration interface (e.g. IConfiguration) and pass this to the constructors of your class. Define virtual methods for all the information needed by the constructors. The constructor can then get its required information by simply calling that method. This is an example on how you could do this:
 
class IConfiguration
   {
   public:
      double getInitialValue() const = 0;
      bool   shouldIDoThisOrThat() const = 0;
   };
 
template <class BT,class ST>
class Factory : public FactoryPlant
   {
   public:
      Factory() {}
      virtual ~Factory() {}
      virtual BT *createInstance(const IConfiguration &config) {return new ST(config);}
   };
 
Enjoy life, this is not a rehearsal !!!

GeneralRe: Here is my template solution.memberebtrexler14 Feb '11 - 7:41 
Patje,
 
Thanks for your reply. It makes perfect sense now.
 
Best,
Brady
GeneralRe: Here is my template solution.memberebtrexler10 Jan '12 - 9:54 
Hi -- Is there any way to query the factory for the types that are registered? I can get the keys used for registration by:
std::vector<TKeyType>GetKeys() {
      std::vector<TKeyType>theVector;
      typedef typeMapKeyToBuilder::const_iterator const_iterator;
      const_iterator theEnd(m_mapKeyToBuilder.end());
      for (const_iterator theIterator(m_mapKeyToBuilder.begin());
         theIterator != theEnd; ++theIterator) {
         theVector.push_back(theIterator->first);
      }
 
      return theVector;
   }
 
Any suggestions for how to get the srcTypes out of the factory's m_mapKeyToBuilder data member?
phalanger wrote:
template<typename TSubType>
          void     registerBuilder(const TKeyType & key,TypeID<TSubType> obj)
          {
               typedef TypeID<TSubType>::objTypeId     srcType;
               typeMapKeyToBuilder::iterator it = m_mapKeyToBuilder.find(key);
               if (it != m_mapKeyToBuilder.end())
                    throw std::runtime_error("duplicate");
               m_mapKeyToBuilder[key] = new TObjBuilder<srcType>();
          }

 
Thanks,
Brady
GeneralFunction 7: staticmemberBitterman4 Mar '03 - 13:25 

class CMe
{
public:
static CMe* Create() { return new CMe; }
static CMe* Create(int parm) { return new CMe; }
}
 
Using this method keeps all the code within the class in question; you do not need an xxx_Factory handler class. You do not need to include the header for the class if you are using just pointers for it, and never are accessing functions, just passing it around.
 


Through 86 years of perpetual motion, if he likes you he'll smile and he'll say,
"Some of it's magic, some of it's tragic, but I had a good life all the way"


GeneralVery good!memberjhwurmbach4 Mar '03 - 3:41 
I really liked your article, as it tried to approach a somewhat 'buzzwordish' theme from a technical point of view.
But I would very much like to see how these factories fit in with the ones from the design patterns books.
 
For me, this is a clear 5.
 

My opinions may have changed, but not the fact that I am right.
QuestionA little on the concept?memberChopper4 Mar '03 - 3:02 
When talking about factories it is suggested to emphasize on the concept of such with some simple diagrams of functionality of factory classes, and what they are for. Otherwise, the word "factory" makes a little difference from word "plant", for example.
 
It just would be a good plus to your article. Just a thought.
Other than that, the article seems good.
 

 
Regards,
Vitaly Tomilov
 

Professional tooltips for all development platforms Free on www.Tooltips.NET


AnswerRe: A little on the concept?memberBitterman4 Mar '03 - 13:26 

"Class factories" are taken from the orignal OLE design. Think CoCreateInstance.
 


Through 86 years of perpetual motion, if he likes you he'll smile and he'll say,
"Some of it's magic, some of it's tragic, but I had a good life all the way"


GeneralRe: A little on the concept?memberChopper5 Mar '03 - 4:35 
Personally, i know everything threre's to know about COM, (after 4 years of "playing" with it) but it doesn't change in any way what i wrote about with respect to other readers who only begin learning COM.
 

Regards,
Vitaly Tomilov
 

Professional tooltips for all development platforms Free on www.Tooltips.NET


General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 27 Mar 2003
Article Copyright 2003 by Patje
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid