[创建型模式] head first 设计模式之工厂模式(Factory)

1 概述
工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。工厂模式有以下几种形态:
[color=red]a) 简单工厂(Simple Factory)模式[/color]
专门定义一个类来负责创建其它类的实例,被创建的实例通常都具有共同的父类。
注意:简单工厂模式并不包含在23种模式之内。
[img]http://dl2.iteye.com/upload/attachment/0091/6096/8721053b-0b3a-3ffc-ba99-9fbdc6402b3c.png[/img]


[color=red] b) 工厂方法(Factory Method)模式,又称多形性工厂(Polymorphic Factory)模式[/color]
将对象的创建交由父类中定义的一个标准方法来完成,而不是其构造函数,究竟应该创建何种对象由具体的子类负责决定。[color=red]通过继承来实现的。[/color]
[img]http://dl2.iteye.com/upload/attachment/0091/6108/b23b1d4c-366b-3064-b7a2-6f19164ae854.png[/img]

[color=red]c) 抽象工厂(Abstract Factory)模式,又称工具箱(Kit或Toolkit)模式[/color]
提供一个共同的接口来创建相互关联的多个对象。[color=red]通过组合来实现的,但是抽象工厂中创建产品的方法通常是以“工厂方法”来实现的[/color]

[img]http://dl2.iteye.com/upload/attachment/0091/6123/34023d11-556f-3377-b883-6820347e8ed3.png[/img]

GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。

2 说明
工厂方法用来处理对象的创建,并将这样的行为封装在子类中。这样,客户程序中关于超类的代码就和子类对象创建代码解耦了。
工厂模式定义:实例化对象,用工厂方法代替new操作。



工厂方法模式 抽象工厂模式

针对的是一个产品等级结构 针对的是面向多个产品等级结构
一个抽象产品类 多个抽象产品类
可以派生出多个具体产品类 每个抽象产品类可以派生出多个具体产品类
一个抽象工厂类,可以派生出多个具体工厂类 一个抽象工厂类,可以派生出多个具体工厂类
每个具体工厂类只能创建一个具体产品类的实例 每个具体工厂类可以创建多个具体产品类的实例

3小结
★工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继承或者是单个类都是可以的。但要明确的,工厂模式的接口只会返回一种类型的实例,这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。
★使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。
★工厂模式返回的实例可以不是新创建的,返回由工厂创建好的实例也是可以的。


4 区别
[color=red]简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族) [/color]

简单工厂代码示例

class Light
{
public:
virtual void TurnOn() = 0;
virtual void TurnOff() = 0;
};

class BulbLight : public Light
{
public:
virtual void TurnOn()
{
cout << "Bulb Light is Turned on\n";
}

virtual void TurnOff()
{
cout << "Bulb Light is Turned off\n";
}
};

class TubeLight : public Light
{
public:
virtual void TurnOn()
{
cout << "Tube Light is Turned on\n";
}

virtual void TurnOff()
{
cout << "Tube Light is Turned off\n";
}
};

typedef enum EM_LightType
{
LightType_Bulb,
LightType_Tube,
}LightType;

class LightSimpleFactory
{
public:
Light* Create(LightType emLightType)
{
if(LightType_Bulb == emLightType)
{
return new BulbLight();
}
else if(LightType_Tube == emLightType)
{
return new TubeLight();
}
else
{
return NULL;
}
}
};

class LightSimpleFactoryTest
{
public:
void run()
{
LightSimpleFactory* pFactory = new LightSimpleFactory();

Light* pLight = pFactory->Create(LightType_Bulb);
pLight->TurnOn();
pLight->TurnOff();
delete pLight;

cout <<"-----------------\n";

pLight = pFactory->Create(LightType_Tube);
pLight->TurnOn();
pLight->TurnOff();
delete pLight;

delete pFactory;
}
};


工厂方法示例
[img]http://t25-1.yunpan.360.cn/p/800-600.ebbf07c05042173fa5d0ef5181665565d7744b9a.bea5d5.jpg?t=4264dce59eaeb5c98815a75bda9d7e40&d=20130820[/img]



#ifndef FACTORY_H
#define FACTORY_H

#include <iostream>
#include <string>
#include <list>
#include <cassert>
using namespace std;

//工厂模式
namespace Factory
{
//const definitions
//
typedef list<string> ToppingList;

//
class Pizza
{
public:
const char* getName()
{
return m_Name.c_str();
}

void prepare()
{
// class PizzaIngredientFactory
// {
// public:
// Dough* creatDough() { return new Dough(); }
// Sauce* creatSauce() { return new Sauce(); }
// };
// PizzaIngredientFactory ingredientFactory;
//
// m_Dough = ingredientFactory.creatDough();
// m_Sauce = ingredientFactory.creatSauce();

cout << "Preparing " << m_Name.c_str() << endl;
cout << "Tossing dough..." << endl;
cout << "Adding sauce..." << endl;
cout << "Adding topping: " << endl;

ToppingList::const_iterator iter = m_Toppings.begin();
ToppingList::const_iterator end = m_Toppings.end();
for ( ; iter != end; ++iter)
{
cout << " " << (*iter).c_str();
}
cout << endl;
}

void bake()
{
cout << "Bake for 25 minutes at 350" << endl;
}

void cut()
{
cout << "Cutting the pizza into diagonal slices" << endl;
}

void box()
{
cout << "Place pizza in official PizzaStore box" << endl;
}

protected:
string m_Name;
string m_Dough;
string m_Sauce;
ToppingList m_Toppings;
};

//
class NYStyleCheesePizza : public Pizza
{
public:
NYStyleCheesePizza()
{
m_Name = "NY Style Sauce and cheese Pizza";
m_Dough = "Thin Crust Dough";
m_Sauce = "Marinara Sauce";
m_Toppings.push_back(string("Grated Reggiano Cheese"));
}
};

//
class ChicagoStyleCheesePizza : public Pizza
{
public:
ChicagoStyleCheesePizza()
{
m_Name = "Chicago Style Deep Dish cheese Pizza";
m_Dough = "Extra Thick Crust Dough";
m_Sauce = "Plum Tomato Sauce";

m_Toppings.push_back(string("Shredded Mozzarella Cheese"));
}

void cut()
{
cout << "Cutting the pizza into square slices" << endl;
}
};

//
class PizzaStore
{
public:
Pizza* orderPizza( string type)
{
if (m_Pizza != NULL)
{
delete m_Pizza;
m_Pizza = NULL;
}

m_Pizza = createPizza(type);

if ( m_Pizza != NULL)
{
m_Pizza->prepare();
m_Pizza->bake();
m_Pizza->cut();
m_Pizza->box();
}

return m_Pizza;
}

PizzaStore()
: m_Pizza(NULL)
{}

virtual ~PizzaStore()
{
if (m_Pizza!=NULL)
{
delete m_Pizza;
m_Pizza = NULL;
}
}

protected:
virtual Pizza* createPizza(string type) = 0;

protected:
Pizza* m_Pizza;
};

//the factory
//
class NYStylePizzaStore : public PizzaStore
{
public:
virtual Pizza* createPizza(string type)
{
if (type == "cheese")
{
m_Pizza = new NYStyleCheesePizza();
}
else if (type == "pepperoni")
{
//m_Pizza = new NYStylePepperoniPizza();
}
else if (type=="clam")
{
//m_Pizza = new NYStyleClamPizza();
}
else if (type=="veggie")
{
//m_Pizza = new NYStyleVeggiePizza();
}
else
{
m_Pizza = NULL;
}

return m_Pizza;
}
};

//
class ChicgoStytlePizzaStore : public PizzaStore
{
public:
virtual Pizza* createPizza(string type)
{
if (type == "cheese")
{
m_Pizza = new ChicagoStyleCheesePizza();
}
else if (type == "pepperoni")
{
//m_Pizza = new ChicagoStylePepperoniPizza();
}
else if (type=="clam")
{
//m_Pizza = new ChicagoStyleClamPizza();
}
else if (type=="veggie")
{
//m_Pizza = new ChicagoStyleVeggiePizza();
}
else
{
m_Pizza = NULL;
}

return m_Pizza;
}
};

//
class PizzaTestDrive
{
public:
void run()
{
PizzaStore* nyStore = new NYStylePizzaStore();
PizzaStore* chicagoStore = new ChicgoStytlePizzaStore();

Pizza* pizza = nyStore->orderPizza("cheese");
assert(pizza != NULL);
cout << "Ethan ordered a " << pizza->getName() << endl;

pizza = chicagoStore->orderPizza("cheese");
assert(pizza != NULL);
cout << "Joel ordered a " << pizza->getName() << endl;

delete nyStore;
delete chicagoStore;
}
};

}//namespace Factory

#endif


[img]http://t25-2.yunpan.360.cn/p/800-600.9a8ed69c02cb10342602537560203de1c25aa97a.dd1367.jpg?t=4264dce59eaeb5c98815a75bda9d7e40&d=20130820[/img]
抽象工厂示例

#include <iostream>
using namespace std;

class AbstractProductA
{
public:
virtual ~AbstractProductA(){}

protected:
AbstractProductA(){}

private:
};

class AbstractProductB
{
public:
virtual ~AbstractProductB(){}

protected:
AbstractProductB(){}
};

class ProductA1 : public AbstractProductA
{
public:
ProductA1()
{
cout<<"ProductA1..."<<endl;
}
~ProductA1(){}
};

class ProductA2 : public AbstractProductA
{
public:
ProductA2()
{
cout<<"ProductA2..."<<endl;
}

~ProductA2(){}
};

class ProductB1 : public AbstractProductB
{
public:
ProductB1()
{
cout<<"ProductB1..." << endl;
}
~ProductB1(){}
};

class ProductB2 : public AbstractProductB
{
public:
ProductB2()
{
cout<<"ProductB2..." << endl;
}
~ProductB2(){}
};

//
class AbstractFactory
{
public:
virtual ~AbstractFactory(){}
virtual AbstractProductA *CreateProductA() = 0;
virtual AbstractProductB *CreateProductB() = 0;

protected:
AbstractFactory(){}

};

class ConcreteFactory1 : public AbstractFactory
{
public:
ConcreteFactory1()
{
}

~ConcreteFactory1()
{
}

AbstractProductA* CreateProductA()
{
return new ProductA1();
}

AbstractProductB* CreateProductB()
{
return new ProductB1();
}
};

class ConcreteFactory2 : public AbstractFactory
{
public:
ConcreteFactory2(){}
~ConcreteFactory2(){}

AbstractProductA *CreateProductA()
{
return new ProductA2();
}

AbstractProductB *CreateProductB()
{
return new ProductB2();
}
};

//
int main(int argc, char *argv[])
{
AbstractFactory *cf1 = new ConcreteFactory1();
cf1->CreateProductA();
cf1->CreateProductB();

AbstractFactory *cf2 = new ConcreteFactory2();
cf2->CreateProductA();
cf2->CreateProductB();

return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值