简单工厂模式
// Factory.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
using namespace std;
class Product
{
public:
virtual void show() = 0;
};
class Product_A : public Product
{
public:
void show()
{
cout << "Product_A" << endl;
}
};
class Product_B : public Product
{
public:
void show()
{
cout << "Product_B" << endl;
}
};
class Factory
{
public:
Product* Create(int i)
{
switch (i)
{
case 1:
return new Product_A;
break;
case 2:
return new Product_B;
break;
default:
break;
}
}
};
int main()
{
Factory *factory = new Factory();
factory->Create(1)->show();
factory->Create(2)->show();
system("pause");
return 0;
}
这种模式不好拓展,需要修改Factory类来实现拓展
简单工厂模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了开闭原则,所以,从设计角度考虑,有一定的问题,如何解决?我们可以定义一个创建对象的抽象方法并创建多个不同的工厂类实现该抽象方法,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。这种方法也就是我们接下来要说的工厂方法模式。
工厂方法模式
#include "stdafx.h"
#include <iostream>
using namespace std;
class Product {
public:
virtual void show() = 0;
};
class Product_A : public Product {
public:
void show() { cout << "Product_A" << endl; }
};
class Product_B : public Product {
public:
void show() { cout << "Product_B" << endl; }
};
class Factory {
public:
virtual Product *create() = 0;
};
class Factory_A : public Factory {
public:
Product *create() { return new Product_A; }
};
class Factory_B : public Factory {
public:
Product *create() { return new Product_B; }
};
int main() {
Factory_A *productA = new Factory_A();
Factory_B *productB = new Factory_B();
productA->create()->show();
productB->create()->show();
system("pause");
return 0;
}
工厂方法存在的问题与解决方法:客户端需要创建类的具体的实例。简单来说就是用户要订纽约工厂的披萨,他必须去纽约工厂,想订伦敦工厂的披萨,必须去伦敦工厂。 当伦敦工厂和纽约工厂发生变化了,用户也要跟着变化,这无疑就增加了用户的操作复杂性。为了解决这一问题,我们可以把工厂类抽象为接口,用户只需要去找默认的工厂提出自己的需求(传入参数),便能得到自己想要产品,而不用根据产品去寻找不同的工厂,方便用户操作。这也就是我们接下来要说的抽象工厂模式。
抽象工厂模式
#include <iostream>
using namespace std;
//定义抽象类
class product1
{
public:
virtual void show() = 0;
};
//定义具体类
class product_A1 :public product1
{
public:
void show(){ cout << "product A1" << endl; }
};
class product_B1 :public product1
{
public:
void show(){ cout << "product B1" << endl; }
};
//定义抽象类
class product2
{
public:
virtual void show() = 0;
};
//定义具体类
class product_A2 :public product2
{
public:
void show(){ cout << "product A2" << endl; }
};
class product_B2 :public product2
{
public:
void show(){ cout << "product B2" << endl; }
};
class Factory
{
public:
virtual product1 *creat1() = 0;
virtual product2 *creat2() = 0;
};
class FactoryA
{
public:
product1 *creat1(){ return new product_A1(); }
product2 *creat2(){ return new product_A2(); }
};
class FactoryB
{
public:
product1 *creat1(){ return new product_B1(); }
product2 *creat2(){ return new product_B2(); }
};
int main()
{
FactoryA *factoryA = new FactoryA();
factoryA->creat1()->show();
factoryA->creat2()->show();
FactoryB *factoryB = new FactoryB();
factoryB->creat1()->show();
factoryB->creat2()->show();
return 0;
}
解决了工厂方法模式的问题:在抽象工厂中PizzaStroe中只需要传入参数就可以实例化对象。
1.4 工厂模式适用的场合
大量的产品需要创建,并且这些产品具有共同的接口 。
1.5 三种工厂模式的使用选择
简单工厂 : 用来生产同一等级结构中的任意产品。(不支持拓展增加产品)
工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增加产品)
抽象工厂 :用来生产不同产品族的全部产品。(支持拓展增加产品;支持增加产品族)
简单工厂的适用场合:只有伦敦工厂(只有这一个等级),并且这个工厂只生产三种类型的pizza:chesse,pepper,greak(固定产品)。
工厂方法的适用场合:现在不光有伦敦工厂,还增设了纽约工厂(仍然是同一等级结构,但是支持了产品的拓展),这两个工厂依然只生产三种类型的pizza:chesse,pepper,greak(固定产品)。
抽象工厂的适用场合:不光增设了纽约工厂(仍然是同一等级结构,但是支持了产品的拓展),这两个工厂还增加了一种新的类型的pizza:chinese pizza(增加产品族)。
所以说抽象工厂就像工厂,而工厂方法则像是工厂的一种产品生产线。因此,我们可以用抽象工厂模式创建工厂,而用工厂方法模式创建生产线。比如,我们可以使用抽象工厂模式创建伦敦工厂和纽约工厂,使用工厂方法实现cheese pizza和greak pizza的生产。类图如下: