I don´t get it. All your account types are unrelated, they´re neither derived from any other class nor are they base class of any other class. Why do you need a separate factory class for each of your account types? Don´t make things more complicated than they really are, just use an if-else clause like
D_Drmmr already suggested. You can move the account creation into a factory, so you have one factory object that creates an account object depending on the login type. Specifying an interface for the factory allows extension and adding other factories later.
There are two possible scenarios that come into my mind:
1) A factory that creates instances of a fixed set of accounts:
Code:
class AbstractAccountFactory
{
public:
virtual ~AbstractAccountFactory();
UserAccount create_user_account() virtual = 0;
AdminAccount create_admin_account() virtual = 0;
StaffAccount create_staff_account() virtual = 0;
};
class Win32AccountFactory : public AbstractFactory
{
...
};
class UnixAccountFactory : public AbstractFactory
{
...
};
I don´t know if the example above makes any sense, but it demonstrates how to use the abstract factory pattern to create instances of a fixed set of object types.
The other scenario is a hierachy where all accounts are derived from a base account class and the factory decides which derived class to instantiate depending on the login type. This fits the case you are describing:
You can even create an InvalidAccount account type and return it instead of returning 0 or throwing an exception. The InvalidAccount simply fails on all operations made on it.
Actually, my purpose is to learn abstract factory, factory method and OOP. Your second approach is not bad but need if statement.
I have a solution like this My solution is like this. Basically, there are two hierarchy which are ObjecFactory which have three derived classes which are AdminFactory, HRFactory and StaffFactory. Another class hierarchy is wraps login session inside usernameType which have three derived classes also same as above.
I was thinking the difficulties in creating concrete usernameType then forward to concrete objectFactory to create the object. Now, i have solution which is using factory method in usernameType hierarchy. Is this possible ?
Thanks.
Please comment on this approach rather spoon feed me with some code and explain why this approach doesn't works and other approach is better.
Thanks.
Last edited by Peter_APIIT; June 25th, 2009 at 05:16 AM.
1) You have got a username string whose first character specifies which account type to create
2) You don´t want to use if-else statements to find the appropriate account type
3) You want to use a separate factory object to create an account depending on the username information
Some other people and me commented your approach and all of them told you NOT to use different objects to create account objects or use an if-else/switch statement respectively.
You, on the other side, ignore all these comments and insist on your approach, no matter how unsuitable it is.
No matter what and no matter how you do it, at some point you have to look at the first character of the username, there´s simply no other way except for magic.
Furthermore, your account types are unrelated, they have no common base class, so the abstract factory pattern might not be applied at all. If the sole purpose of this thread is to get an understanding of how to use the abstract factory pattern then you better choose and example where it can be applied.
Please explain how your design fits together with the abstract factory pattern
Last edited by GNiewerth; June 25th, 2009 at 06:46 AM.
GNiewerth's code example is presumably only meant to illustrate the idea, but I note that AbstractAccountFactory::create_account() was not declared pure virtual, probably by accident, and this omission would affect the idea to be illustrated. (AbstractAccount also is not actually an abstract base class, but that can be pardoned, methinks )
Also, if you do want to convert the example to something compilable, perhaps this would be a better way of implementing the create_account free function:
Code:
// Scenario 1: strAccount is a std::string
AbstractAccount* create_account(const std::string& strAccount)
{
std::auto_ptr<AbstractAccountFactory> Factory;
if (!strAccount.empty())
{
switch (strAccount[0])
{
case 'H':
Factory.reset(new HRAccountFactory());
break;
case 'A':
Factory.reset(new AdminAccountFactory());
break;
case 'S':
Factory.reset(new StaffAccountFactory());
break;
}
}
return Factory.get() ? Factory->create_account() : 0;
}
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar
My last question is does AbstractAccount corresponds to my usernameType. If there is no abstractProduct, What is the return type of createInstance() in factory class.
Does my situation suitable for abstract factory ?
Thanks.
Last edited by Peter_APIIT; June 26th, 2009 at 07:08 PM.
Objects are only created when that user type login. You can add more user types without touching the base factory class. Just copy 2 files (like Admin.h and Admin.cpp), then rename the files, replace "Admin" with something else in the content, add to the solution, compile and voila.
Let me know if this is what you want.
Last edited by zerocool2k; June 27th, 2009 at 02:31 AM.
Thanks, i have coded this myself with two two design patterns which are abstract factory and factory method. Although, the solution is unnecessary bu learn two DP.
I just notice the destructors in my example were never called. Anyone knows why?
I can explicitly call "delete ob" in main() and should not have "delete pAdmin" in its destructor. But how to make this more hidden? (not having to delete in main()? ) Why weren't the destructors called when the program terminates?
Last edited by zerocool2k; June 27th, 2009 at 04:48 PM.
I just notice the destructors in my example were never called. Anyone knows why?
You implement your classes to use the RAII idiom, but then you directly use pointers to dynamically allocated objects, thus you did not actually use the RAII idiom.
Originally Posted by zerocool2k
I can explicitly call "delete ob" in main() and should not have "delete pAdmin" in its destructor. But how to make this more hidden? (not having to delete in main()? ) Why weren't the destructors called when the program terminates?
Use smart pointers. std::tr1::shared_ptr is probably applicable here.
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.