dcsimg


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Page 1 of 2 12 LastLast
Results 1 to 15 of 20

Thread: Difference between Abstract Factory and Factory Method

  1. #1
    Join Date
    May 2007
    Posts
    843

    Difference between Abstract Factory and Factory Method

    Hello to all, What is the difference between Abstract Factory and Factory Method ?

    Thanks.

  2. #2
    Join Date
    Apr 2007
    Location
    Sterling Heights, Michigan
    Posts
    8,663

  3. #3
    Join Date
    Nov 2003
    Posts
    4,118
    "Factory Method" is a misleading name. It refers to what is commonly known as the Factory Pattern, where Factory is a class with a static member function that returns a pointer to Base which is actually pointing to a derived object. See http://www.devx.com/cplus/10%20Minute%20Solution/40887 for a complete C++ example.
    The Abstract Factory is more like a factory used by another factory. In C++ it's less in use than in Java or C#.
    Danny Kalev

  4. #4
    Join Date
    Dec 2003
    Posts
    3,366
    Not to be confused with a class factory, which is a (lesser known) name for things like the visual studio class wizard, which makes empty classes for you and lets you add members to them with mouse clicks instead of typing (of some limited use, I use it to add the event handler methods to the automatically generated classes but its not terribly useful for building your own classes).

  5. #5
    Join Date
    May 2007
    Posts
    843
    The main difference abstract factory and factory pattern(Factory Method) is the former is using object composition(Another hierarchy) and the create method is inside the particular class. The latter is where the create method is located at base class and create subclass as required(Same inheritance hierarchy).

    This is the same case with template method and strategy.

  6. #6
    Join Date
    May 2007
    Posts
    843
    I have try to code the abstract factory.

    Code:
    #ifndef WIDGET_H
    #define WIDGET_H
    
    
    class widget
    {
    public:
    	widget();
    	virtual ~widget();
    	virtual void draw() = 0;
    };
    #endif
    
    #ifndef MACWIDGET_H
    #define MACWIDGET_H
    
    #include "Widget.h"
    
    class MacWidget : public widget
    {
    public:
    	MacWidget();
    	~MacWidget();
    
    	void draw();
    };
    #endif
    
    #ifndef WINDOW_WIDGET_H
    #define WINDOW_WIDGET_H
    
    #include "Widget.h"
    
    class WindowWidget : public widget
    {
    public:
    	void draw();
    };
    #endif
    
    #ifndef WIDGETFACTORY_H
    #define WIDGETFACTORY_H
    
    class widget;
    
    class widgetFactory
    {
    public:
    	virtual widget* createWidget() = 0;
    };
    #endif
    
    #ifndef MAC_WIDGET_FACTORY_H
    #define MAC_WIDGET_FACTORY_H
    
    #include "WidgetFactory.h"
    
    
    class MacWidgetFactory : public widgetFactory
    {
    public:
    	widget* createWidget();
    };
    #endif
    
    #include "MacWidgetFactory.h"
    #include "MacWidget.h"
    
    
    
    widget* MacWidgetFactory::createWidget()
    {
    	return new MacWidget();
    }
    
    
    
    
    
    
    // =========================================
    Please give some opinion and comment.

    Thanks.

  7. #7
    Join Date
    Dec 2007
    Posts
    401
    the widgetFactory class is the abstract factory.

    it is a somewhat unusual use of the abstract factory; usually the abstract factory has more than one factory method for creating different kinds of objects belonging to a family.

    if in addition to

    virtual widget* createWidget() = 0;

    you also had things like

    virtual menu* createMenu( /* ... */ ) = 0;
    virtual font* createFont( /* ... */ ) = 0;

    it would be the normal usage of the abstract factory pattern.


    if you had

    Code:
    class my_program
    {
            public:
                    // lots of stuff - the full functionality of your program
                    // you need to create widgets at several places
                    // which you do by calling the factory method
     
            protected : virtual widget* createWidget() = 0; // factory method
    };
    
    class my_mac_program : my_program
    {
            protected : virtual widget* createWidget()  
                                { return new MacWidget ; }
    };
    
    class my_mswindows_program : my_program
    {
            protected : virtual widget* createWidget()  
                                { return new mswindowsWidget ; }
    };
    etc., virtual widget* createWidget() = 0; would be a factory method.

    an abstract factory
    a. contains factory methods to create different kinds of objects
    b. is usually implemented as a singleton.
    c. the singleton concrete factory is often retrieved via a factory method.
    eg. virtual widgetFactory* getFactory() = 0 ;

  8. #8
    Join Date
    May 2007
    Posts
    843
    I will take your advise to add more factory method to the particular abstract factory.

    class my_program is synonymy to my class widgetFactory.

    My questions now is how to use it in main program ?

    Thanks.

  9. #9
    Join Date
    May 2007
    Posts
    843
    My current code as below:

    Code:
    #ifndef WIDGET_H
    #define WIDGET_H
    
    
    class widget
    {
    public:
    	widget();
    	virtual ~widget();
    	virtual void draw() = 0;
    };
    #endif
    
    #ifndef MACWIDGET_H
    #define MACWIDGET_H
    
    #include "Widget.h"
    
    class MacWidget : public widget
    {
    public:
    	MacWidget();
    	~MacWidget();
    
    	void draw();
    };
    #endif
    
    #ifndef WINDOW_WIDGET_H
    #define WINDOW_WIDGET_H
    
    #include "Widget.h"
    
    class WindowWidget : public widget
    {
    public:
    	void draw();
    };
    #endif
    
    #ifndef WIDGETFACTORY_H
    #define WIDGETFACTORY_H
    
    class widget;
    
    class widgetFactory
    {
    public:
    	virtual widget* createWidget() = 0;
    };
    #endif
    
    #ifndef MAC_WIDGET_FACTORY_H
    #define MAC_WIDGET_FACTORY_H
    
    #include "WidgetFactory.h"
    
    
    class MacWidgetFactory : public widgetFactory
    {
    public:
    	widget* createWidget();
    };
    #endif
    
    #include "MacWidgetFactory.h"
    #include "MacWidget.h"
    
    
    
    widget* MacWidgetFactory::createWidget()
    {
    	return new MacWidget();
    }
    
    #ifndef Window_WIDGET_FACTORY_H
    #define Window_WIDGET_FACTORY_H
    
    #include "WidgetFactory.h"
    
    
    class WindowWidgetFactory : public widgetFactory
    {
    public:
    	// Factory Method
    	widget* createWidget();
    };
    #endif
    
    #include "WindowWidgetFactory.h"
    #include "WindowWidget.h"
    
    
    // =========================================
    widget* WindowWidgetFactory::createWidget()
    {
    	return new WindowWidget();
    }
    
    int main()
    {
    	MacWidgetFactory macFactoryObj;
    	MacWidget* macObj = macFactoryObj.createWidget();
    	
    
    	WindowWidgetFactory windowFactoryObj;
    	WindowWidget* windowObj = windowFactoryObj.createWidget();
    	return 0;
    }

    Error message is

    error C2440: 'initializing' : cannot convert from 'widget *' to 'MacWidget *'
    error C2440: 'initializing' : cannot convert from 'widget *' to 'WindowWidget *'
    Thanks.

  10. #10
    Join Date
    Dec 2007
    Posts
    401
    the purpose of an abstract factory is to enable the creation of objects without knowledge of their concrete implementations (sub-classes).

    modify:
    Code:
    MacWidget* macObj = macFactoryObj.createWidget();
    WindowWidget* windowObj = windowFactoryObj.createWidget();
    to
    Code:
    Widget* macObj = macFactoryObj.createWidget();
    Widget* windowObj = windowFactoryObj.createWidget();
    you haven't solved the problem if you create the factory object yourself.
    a. implement the factory as a singleton.
    b. retrieve it (as an abstract widgetFactory*) via some suitable mechanism (perhaps a factory method in you application class).
    c. abstract factories create families of products which are mutually exclusive.
    ie. it can not be right to use both a MacWidget and a WindowWidget in the same main().

  11. #11
    Join Date
    May 2007
    Posts
    843
    I not really understand what u mentioned here. I think example will clear the confusion.

    Thanks.

  12. #12
    Join Date
    Dec 2007
    Posts
    401
    this site is really, really broke.

    earlier it was chewing up urls.

    now it's got worse; just wasted about half an hour of my time (which i spent in writing a detailed code example as an answer). which it gobbled up without a trace when i tried to post it; it seemed to believe that i was not logged in.
    logged in again and there was no trace of what i had been typing in.

    i just give up.

    bye, everyone.
    Last edited by vijayan; 03-09-2009 at 12:40 PM.

  13. #13
    Join Date
    May 2007
    Posts
    843
    I know this is a bit of disappointed but let help people.

    You can send to my email.

  14. #14
    Join Date
    Dec 2007
    Posts
    401

    part 1 of 4

    consider a program for printing invoices that needs to be localized for different countries.
    we have a central data base (perhaps accessed over the web) that contains pricing information in euros.
    the invoice needs to be printed out in the local currency.
    tax calculations, shipping charge calculations, date format etc vary from country to country.

    the abstract interface currency (include guards are elided)

    Code:
    // -----------  currency.h ---------------------------------------
    #include <string>
    
    struct currency 
    { 
      virtual ~currency() {}    
      virtual std::string str() const = 0 ;   
      virtual double amount() const = 0 ;   
      /* etc */    
    } ;
    concrete implementation of currency for indian rupees

    Code:
    // -----------  inr.h (+ inr.cc) --------------------
    #include <sstream>
    #include <iomanip>
    #include <locale>
    #include "currency.h"
    
    struct inr : currency 
    {  
      explicit inr( double a ) : amt(a) {}
    
      std::string str() const 
      { 
        std::ostringstream stm ; 
    
        // stm.imbue( "en_IN.UTF-8" ) ; // elided
        // std::moneypunct<char> mpunct = std::use_facet< std::moneypunct<char> >( stm.getloc() ) ;  // elided
        // in real code, use the mpunct facet to format amount  
    
        stm << std::fixed << std::showpoint << std::setprecision(2) << "Rs. " << amt ; 
        return stm.str() ;
      }
    
      double amount() const { return amt ; }   
    
      static double conv_rate_from_euros() { return 1.0 / 64.378642 ; }
    
      /* etc */    
    
      private : double amt ;
    } ;
    concrete implementation of currency for japanese yen

    Code:
    // -----------  jyen.h (+ jyen.cc) --------------------
    #include <string>
    #include <sstream>
    #include <iomanip>
    #include <locale>
    #include "currency.h"
    
    struct jyen : currency 
    {  
      explicit jyen( double a ) : amt(a) {}
    
      std::string str() const 
      { 
        std::ostringstream stm ; 
    
        // stm.imbue( "ja_JP.UTF-8" ) ;  // elided
        // std::moneypunct<char> mpunct = std::use_facet< std::moneypunct<char> >( stm.getloc() ) ;  // elided
        // in real code, use the mpunct facet to format amount  
    
        stm << std::fixed << std::showpoint << std::setprecision(3)  << amt << " Japanese yen" ; 
        return stm.str() ;
      }
    
      double amount() const { return amt ; }   
    
      static double conv_rate_from_euros() { return 1.0 / 123.576104 ; }
      /* etc */    
    
      private : double amt ;
    } ;
    other abstract interfaces & and their implementations are elided for brevity

  15. #15
    Join Date
    Dec 2007
    Posts
    401

    part 2 of 4

    the abstract factory

    Code:
    // -----------  inv_tool.h ------------------------------------
    #include "currency.h"
    
    struct invoice_tool // abstract factory + strategy
    {
        virtual currency* create_currency( double amt_in_euros ) const = 0 ; 
        virtual currency* compute_tax( currency* amount ) const = 0 ; 
        virtual currency* compute_shipping_fee( int nitems ) const = 0 ;
    
        // other members of the family; elided for brevity
        // virtual date_formatter* create_date_formatter() = 0 ; 
        // etc
    };
    concrete factory for india

    Code:
    // -----------  india_inv_tool.h (+ india_inv_tool.cc ) --------------------
    #include "inv_tool.h"
    #include "inr.h"
    
    struct india_invoice_tool  :  invoice_tool
    {
        currency* create_currency( double amt_in_euros ) const 
        { return new inr( amt_in_euros * inr::conv_rate_from_euros() )  ; } 
    
        currency* compute_tax( currency* invoice_amount ) const 
        {  return create_currency( invoice_amount->amount() * 0.10 ) ; }
    
        currency* compute_shipping_fee( int nitems ) const 
        {  return create_currency( nitems * 100.0 ) ; }
    
        // virtual date_formatter* create_date_formatter() ;
        // etc
    };
    concrete factory for japan

    Code:
    // -----------  japan_inv_tool.h (+ japan_inv_tool.cc ) --------------------
    #include "inv_tool.h"
    #include "jyen.h"
    
    struct japan_invoice_tool  :  invoice_tool
    {
        currency* create_currency( double amt_in_euros ) const 
        { return new jyen( amt_in_euros * jyen::conv_rate_from_euros() )  ; } 
    
        currency* compute_tax( currency* invoice_amount ) const 
        {  return create_currency( invoice_amount->amount() * 0.14 ) ; }
    
        currency* compute_shipping_fee( int nitems ) const 
        {  return create_currency( nitems * 350.0 ) ; }
    
        // virtual date_formatter* create_date_formatter() ;
        // etc
    };

Similar Threads

  1. C++ Abstract Factory
    By ami in forum C++
    Replies: 1
    Last Post: 12-03-2006, 02:00 PM
  2. Abstract Factory
    By ami in forum C++
    Replies: 1
    Last Post: 11-30-2006, 08:21 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center