简单工厂模式(Simple Factory Pattern)专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类。
简单工厂模式,是一种实例化对象的方式,只要输入需要实例化对象的名字,就可以通过工厂对象的相应工厂函数来制造你需要的对象。
(1)Factory工厂角色(工厂类):
工厂角色即工厂类,是简单工厂模式的核心,负责创建所有实例的内部逻辑,工厂类可以被外界直接调用,创建所需要的产品对象。
(2)Product(抽象产品角色):
抽象产品角色是简单工厂模式所创建的所有对象的父类,负责描述所有实例所共有的公告接口。所创建的具体产品对象都是其子类对象。
(3)ConcreteProduct(具体产品角色):
具体产品角色是简单工厂模式的创建目标。每个具体产品角色都继承了抽象产品角色,需要实现定义在抽象产品中的方法。
简单工厂(Simple Factory)不属于标准的OOP设计模式中的一项,在编写大型C++软件的时候,代码里面会出现很多的类,每次创建对象的时候,都需要通过new 类名称的方式来生成对象,这样一来,用户需要记忆很多类的名称,暂且不管记不记得住,这样的设计使得代码很难维护,类名如果做了改变,那么所有使用类名称的地方都需要去修改,耦合性太强,不符合我们软件设计的思想,Simple Factory就是在这样的需求下诞生的。
我们把对象的创建全部都封装在了SimpleFactory的create方法中,在这里我们传入一个Product就可以创建一个对象,省略了new的过程
#include
#include
using namespace std;
//产品类型的声明,抽象产品
class Product
{
public:
Product(string name) : ProductName(name) {};
virtual void show() = 0;
protected:
string ProductName;
};
//具体产品的声明
class BaoMa :public Product
{
public:
BaoMa(string name) : Product(name) {};
void show()
{
std::cout << "This is BaoMa Product" << char(10);
std::cout << ProductName << char(10);
}
};
//具体产品2 的申明
class BengChi :public Product
{
public:
BengChi(string name) : Product(name) {};
void show()
{
std::cout << "This is Product" << char(10);
std::cout << ProductName << char(10);
}
};
enum ProductType
{
BWM,
BC
};
class SimpleFactory
{
public:
//通过传入的枚举类型,创建对应的对象,返回对象的基类指针
Product* createProduct(ProductType type)
{
switch (type)
{
case BWM:
return new BaoMa("宝马");
break;
case BC:
return new BengChi("奔驰");
break;
default:
std::cout << "你输入了错误的名字" << type << char(10);
break;
}
}
};
int main()
{
//创建简单工厂的实例
SimpleFactory sf;
unique_ptr p1(sf.createProduct(BWM));
unique_ptr p2(sf.createProduct(BC));
p1->show();
p2->show();
return 0;
}
通过产生具体的工厂创建具体的产品,做到了在扩充新产品时,能够达到软件设计的“开-闭”原则
#include
#include
using namespace std;
class AbstractProduct
{
public:
AbstractProduct(string name): _name(name){}
//模拟产品对象的抽象方法
virtual void show() = 0;
protected:
string _name;
};
class ProductA:public AbstractProduct
{
public:
//其实这是一个委托构造函数
ProductA(string name) : AbstractProduct(name) {}
void show()
{
std::cout << "这是一个产品A的对象"; char(10);
std::cout << "string name : " << _name << char(10);
}
};
class ProductB :public AbstractProduct
{
public:
//其实这是一个委托构造函数
ProductB(string name) : AbstractProduct(name) {}
void show() {
std::cout << "这是一个产品B的对象"<< char(10);
std::cout << "string name : " << _name << char(10);
}
};
//定义枚举类型的数据
enum ProductType
{
XIAOMI,
HUAWEI,
};
//定义抽象工厂
class AbstractFactory
{
public:
virtual AbstractProduct* createProduct() = 0;
};
//小米手机工厂
class XiaoMiFactory:public AbstractFactory
{
public:
AbstractProduct* createProduct()
{
std::cout << "调用了小米工厂的创建方法" << char(10);
return new ProductA("小米手机");
}
};
//华为手机工厂
class HuaWeiFactory :public AbstractFactory
{
public:
AbstractProduct* createProduct()
{
std::cout << "调用了华为工厂的创建方法" << char(10);
return new ProductB("华为手机");
}
};
int main()
{
//在这里我们使用智能指针,创建具体工厂
unique_ptr Fac1(new XiaoMiFactory);
unique_ptr Fac2(new HuaWeiFactory);
//通过工厂方法创建产品
unique_ptr Pro1(Fac1->createProduct());
unique_ptr Pro2(Fac2->createProduct());
Pro1->show();
Pro2->show();
return 0;
}
工厂方法可以解决一簇产品(一款产品有多种形态)的问题,并且工厂一次只能生产一种产品;但需要一个工厂能够同时生产多款产品时,则需要用到抽象工厂模式
仔细理解上面的工厂方法模式,会发现一个问题,就是每一个实例工厂负责生产一个实例产品,也就是一个产品对应一个工厂,一个工厂对应一个产品,那么小米不仅仅生产手机,还生产耳机,智能手环,智能插座等等相关的小米产品簇,不可能给这每一个产品都创建一个工厂类,那样的话代码中的类就太多了,不好维护,而且也不符合实际情况。
实际上小米或者华为的工厂里面,有相关联的产品簇都是在一个工厂完成创建的;BMW或者Audi汽车制造工厂除了生产汽车,生产线上也有可能生产轮胎,或者其它的汽车附属产品。
所以对于包含产品簇这么一类实体关系的设计,就需要使用Abstract Factory抽象工厂了,你也可以把上面的工厂方法看作只生产一种产品的抽象工厂,本质是相同的。
可以看到,抽象工厂模式把一个产品簇的产品放在一个工厂类中去创建,不仅大大减少了工厂类的个数,更符合现实中工厂生产产品的模式。根据上面的内容描述,仔细思考简单工厂,工厂方法和抽象工厂的区别联系。
#include
using namespace std;
//抽象产品 手机类
class AbstractPhone
{
public:
AbstractPhone(string name) : _name(name) {};
//模拟产品对象的一个抽象的方法
virtual void show() = 0;
protected:
string _name;
};
//产品实体类型 小米
class XiaoMiPhone: public AbstractPhone
{
public:
XiaoMiPhone(string name) : AbstractPhone(name) {};
void show()
{
std::cout << "这是" << _name << "手机" << char(10);
}
};
//产品实体类型 华为
class HuaweiPhone : public AbstractPhone
{
public:
HuaweiPhone(string name) : AbstractPhone(name) {};
void show()
{
std::cout << "这是" << _name << "手机" << char(10);
}
};
//抽象产品 手环
class AbstractCircle
{
public:
AbstractCircle(string name) : _name(name) {};
//模拟产品对象的一个抽象的方法
virtual void show() = 0;
protected:
string _name;
};
//产品实体 小米手环
class XiaoMiCircle:public AbstractCircle
{
public:
XiaoMiCircle(string name) :AbstractCircle(name) {};
void show()
{
std::cout << "这是" << _name << "手环" << char(10);
}
};
//产品实体 华为手环
class HuaWeiCircle :public AbstractCircle
{
public:
HuaWeiCircle(string name) :AbstractCircle(name) {};
void show()
{
std::cout << "这是" << _name << "手环" << char(10);
}
};
//抽象工厂,创建一个产品族的设备的产品
class AbstractFactory
{
public:
//创建手机的纯虚函数
virtual AbstractPhone* createPhone() = 0;
virtual AbstractCircle* createCircle() = 0;
};
//生产小米的工厂
class XiaoMiFactory:public AbstractFactory
{
public:
virtual AbstractPhone* createPhone()
{
return new XiaoMiPhone("小米14Pro");
}
virtual AbstractCircle* createCircle()
{
return new XiaoMiCircle("小米手环NFC版本");
}
};
//生产华为的工厂
class HuaWeiFactory :public AbstractFactory
{
public:
virtual AbstractPhone* createPhone()
{
return new XiaoMiPhone("华为Mate60 pro");
}
virtual AbstractCircle* createCircle()
{
return new XiaoMiCircle("华为GT Runing");
}
};
int main()
{
//利用智能指针,创建生产的工厂
unique_ptr< AbstractFactory> fac1(new XiaoMiFactory);
unique_ptr< AbstractFactory> fac2(new HuaWeiFactory);
//通过工厂来生产手机的
unique_ptr< AbstractPhone > phone1(fac1->createPhone());
unique_ptr< AbstractPhone > phone2(fac2->createPhone());
phone1->show();
phone2->show();
//生产手环
unique_ptr< AbstractCircle > cir1(fac1->createCircle());
unique_ptr< AbstractCircle > cir2(fac2->createCircle());
cir1->show();
cir2->show();
return 0;
}