zoukankan      html  css  js  c++  java
  • 设计模式之工厂模式

    一、简介
      工厂模式属于创建型模式,大致上可以分三类:
      1)、简单工厂模式(Simple Factory)
      2)、工厂方法模式(Simple Factory)
      3)、抽象工厂模式(Simple Factory)
      这三种模式是逐步抽象,并且更具一般性。另有一种分法就是将简单工厂模式看作是工厂方法的一种特例,归为一类模式。如下是使用工厂模式的情况:
      1.在编码时不能预见需要创建哪种类的实例
      2.系统不应依赖于产品类实例如何被创建、组合和表达的细节,对于使用者来说是透明的

    二、目标
      目标:提高内聚(Cohesion)和松耦合(Coupling)
      最重要的功能:
      1)、定义创建对象的接口,封装了对象的创建;
      2)、使得具体化类的工作延迟到了子类中

    三、实现

    简单工厂

    enum CTYPE {PRODUCT_A, {PRODUCT_B};   
    class Product  
    {  
    public:  
        virtual void Display() = 0;
    };  
      
    class ProductA: public Product
    {  
    public:  
        void Display() { cout<<"Display A"<<endl; }  
    };  
    
    class ProductB: public Product    
    {  
    public:  
        void Display() { cout<<"Display B"<<endl; }  
    };  
     
    class Factory  
    {  
    public:   
        Product* CreateProduct(enum CTYPE ctype)  
        {  
            if(ctype == PRODUCT_A) 
                return new ProductA();  
            else if(ctype == PRODUCT_B)  
                return new ProductB(); 
            else  
                return NULL;  
        }  
    };

    工厂方法

    enum CTYPE {PRODUCT_A, {PRODUCT_B};   
    class Product  
    {  
    public:  
        virtual void Display() = 0;
    };  
      
    class ProductA: public Product
    {  
    public:  
        void Display() { cout<<"Display A"<<endl; }  
    };  
    
    class ProductB: public Product    
    {  
    public:  
        void Display() { cout<<"Display B"<<endl; }  
    }; 
    
    class Factory    
    {    
    public:    
        virtual Product* CreateProduct() = 0;  
    };    
      
    class FactoryA: public Factory    
    {    
    public:    
        ProductA* CreateProduct() { return new ProductA; }    
    };    
      
    class FactoryB: public Factory    
    {    
    public:    
        ProductB* CreateProduct() { return new ProductB; }    
    }; 
    

    抽象工厂

    enum CTYPE {PRODUCT_A, {PRODUCT_B};   
    class Product  
    {  
    public:  
        virtual void Display() = 0;
    };  
      
    class ProductA: public Product
    {  
    public:  
        void Display() { cout<<"Display A"<<endl; }  
    };  
    
    class ProductB: public Product    
    {  
    public:  
        void Display() { cout<<"Display B"<<endl; }  
    }; 
    
     
    class MultiProduct  
    {  
    public:  
        virtual void Display() = 0;
    };  
    class MultiProductA : public MultiProduct  
    {  
    public:  
        void Display() { cout<<"Multi Product A"<<endl; }  
      
    };  
    class MultiProductB : public MultiProduct  
    {  
    public:  
        void Display() { cout<<"Multi Product B"<<endl; }  
    };  
    
    class Factory    
    {  
    public:  
        virtual Product* CreateProduct() = 0;
        virtual MultiProduct* CreateMultiProduct() = 0;
    };  
     
    class FactoryA :public Factory    
    {  
    public:  
        Product* CreateProduct() { return new ProductA(); }  
        MultiProduct* CreateMultiProduct() { return new MultiProductA(); }  
    };  
    
    class FactoryB : public Factory    
    {  
    public:  
        Product* CreateProduct() { return new ProductB(); }  
        MultiProduct* CreateMultiProduct() { return new MultiProductB (); }  
    }; 
    

    如下是本人用模板实现的通用的性工厂模式:(推荐大家采用本实现)

    #ifndef CRREATEFACTORY_H
    #define CRREATEFACTORY_H
    
    #include <map>
    #include <string>
    
    template<typename Product, typename ConcreteProduct>
    class ConcreteCreator
    {
    public:
    	static Product* CreateConcreteProduct()
    	{
    		return new ConcreteProduct();
    	}
    };
    
    template<typename Product>
    class CreatorFactory
    {
    public:
    	static CreatorFactory& Instance()
    	{
    		static CreatorFactory<Product> instance;
    		return instance;
    	}
    
    public:
    	typedef Product* (*CreateProductDelegate)();
    	typedef std::map<std::string, CreateProductDelegate> MapFactories;
    
    	template<typename ConcreteProduct>
    	void RegisterFactory(const std::string& factoryName)
    	{
    		m_factories[factoryName] = ConcreteCreator<Product, ConcreteProduct>::CreateConcreteProduct;
    	}
    
    	void UnregisterFactory(const std::string& factoryName)
    	{
    		if(m_factories.size() > 0)
    		{
    			MapFactories::iterator it = m_factories.find(factoryName);
    			if(it != m_factories.end())
    			{
    				m_factories.erase(it);
    			}
    		}
    	}
    
    	void UnregisterFactories()
    	{
    		m_factories.clear();
    	}
    
    	Product* CreateProduct(const std::string& factoryName)
    	{
    		MapFactories::iterator type = m_factories.find(factoryName);
    		if (type != m_factories.end())
    		{
    			CreateProductDelegate create = type->second;
    			if (create != 0)
    				return create();
    		}
    		return 0;
    	}
    
    	void ReleaseProduct(Product** product)
    	{
    		if(*product)
    		{
    			Product* p = *product;
    			*product = 0;
    
    			delete p;
    			p = 0;
    		}
    	}
    
    private:
    	CreatorFactory() {}
    	~CreatorFactory() {}
    	CreatorFactory(const CreatorFactory&);
    	CreatorFactory& operator=(const CreatorFactory&);
    
    private:
    	MapFactories m_factories;
    };
    #endif//CRREATEFACTORY_H
    
    
    #include <stdio.h>
    
    #include<iostream>  
    #include<string>  
    #include <limits>
    
    #include "CreatorFactory.h"
    
    using namespace std;
    
    class CBase
    {
    public:
    };
    
    class Person : public CBase
    {
    public:
    };
    
    class Age : public CBase
    {
    public:
    };
    
    class Gender : public CBase
    {
    public:
    };
    
    #include <string.h>
    #include <typeinfo.h>
    #include <stdio.h>
    
    class Base
    {
    public:
    	Base()
    	{
    		strcpy(name,"Base");
    	}
    
    	virtual void display()
    	{
    		cout<<"Display Base."<<endl;
    	}
    
    	virtual void printName()
    	{
    		printf("printf base
    ");
    	}
    
    protected:
    	char name[64];
    };
    
    class Child1:public Base
    {
    public:
    	Child1()
    	{
    		strcpy(name,"Child1");
    	}
    
    	void display()
    	{
    		cout<<"Display Child1."<<endl;
    	}
    
    	virtual void printName()
    	{
    		Base::printName();
    		printf("printf Child1
    ");
    	}
    };
    
    class Child2:public Base
    {
    public:
    	Child2()
    	{
    		strcpy(name,"Child2");
    	}
    
    	void display()
    	{
    		cout<<"Display Child2."<<endl;
    	}
    
    	virtual void printName()
    	{
    		Base::printName();
    		printf("printf Child2
    ");
    	}
    };
    
    void Process(Base *type)
    {
    	if( (typeid(Child1)) == (typeid(*type)) )
    	{
    		((Child1*)type)->display();
    		printf("Process name = %s
    ", typeid(*type).name());
    	}
    	else if( (typeid(Child2)) == (typeid(*type)) )
    	{
    		((Child2*)type)->display();
    		printf("Process name = %s
    ", typeid(*type).name());
    	}
    	else
    	{
    		cout<<"Unknow type!"<<endl;
    	}
    }
    
    int main()
    {
    	cout << "bool: 		" << "所占字节数:" << sizeof(bool) << endl;  
    	int max = (numeric_limits<bool>::max)();
    	int min = (numeric_limits<bool>::min)();
    	
    	typedef CreatorFactory<CBase> PersonFactory;  
    	PersonFactory& factory = PersonFactory::Instance();  
    	factory.RegisterFactory<Person>("Person");  
    	factory.RegisterFactory<Age>("Age");  
    	factory.RegisterFactory<Gender>("Gender");  
    
    	CBase* person = factory.CreateProduct("Person");
    	CBase* age = factory.CreateProduct("Age");
    	CBase* gender = factory.CreateProduct("Gender");
    
    	factory.UnregisterFactory("Age");
    	factory.ReleaseProduct(&age);
    	factory.UnregisterFactory("Henry");
    
    	Base *pT1 = new Child1();
    	Base *pT2 = new Child2();
    	
    	Process(pT1);
    	Process(pT2);
    
    	pT1->printName();
    	pT2->printName();
    
    	printf("OK/n");
    
    	getchar();
    	return 0;
    }

    如果本工厂方法用gcc编译应该会有错误提示,那是因为gcc的要求非常严格:error: expected ';' before it.这时就需要在MapFactoried::iterator 前面加typename.
    就可以修正这个bug。请参看《C++ Primer》中的“模板与泛型编程”
  • 相关阅读:
    JasperReport html 导出
    mysql 序列号生成器 (自定义函数)
    [Java][Spring]Spring事务不起作用 问题汇总
    序列 mysql
    订单编号
    Mybatis
    SNMP 配置
    Gradle 1.12用户指南翻译——第三十八章. Eclipse 插件
    cocos2dx2.0 与cocos2dx3.1 创建线程不同方式总结
    Android实战简易教程-第二十八枪(Uri转String型实例)
  • 原文地址:https://www.cnblogs.com/wenrenhua08/p/3933631.html
Copyright © 2011-2022 走看看