什么是工厂模式
工厂模式(Factory Pattern)是一种创建对象的设计模式,它提供了一种封装对象创建过程的方式,以便于客户端代码使用抽象接口来创建对象,而无需关心具体的对象实现类。
工厂模式的核心思想是将对象的创建逻辑封装在一个工厂类中,客户端通过与工厂类交互来创建所需的对象。也就是说, 工厂可以生产产品,而客户只需要调用工厂提供的接口得到想要的产品。
工厂模式设计有三种: 简单工厂模式, 工厂模式, 抽象工厂模式。
1. 简单工厂模式
首先, 简单工厂模式会提供一个产品的抽象类,然后根据这个产品抽象类派生出一系列的具体产品类。(抽象类就相当于还是概念产品, 派生类就是实际落地的产品,工厂给用户的产品就是派生类的实例对象。)
在shop.h中, 定义了一个抽象类,它代表了一个抽象产品,可以通过cost()得到购买商品的花销,get()可以得到商品的效果(恢复HP)。
随后,派生出具体的商品类(Littleshop、Middleshop、Bigshop),在派生类中通过函数重写实现了cost()和get()接口。
//shop.h
#pragma once//(c++11 特性)相当于ifndef def endif
#include <iostream>
class Abstractshop//抽象商品类
{
public:
virtual void cost() {}
virtual void get() {}
virtual ~Abstractshop() {}
};
class Littleshop : public Abstractshop
{
public:
void cost() override//(c++11 特性) 显式声明函数重写,禁止函数隐藏,这是为了实现多态
{
std::cout << "cost 10$" << std::endl;
}
void get() override
{
std::cout << "Hp + 10" << std::endl;
}
};
class Middleshop : public Abstractshop
{
public:
void cost() override
{
std::cout << "cost 15$" << std::endl;
}
void get() override
{
std::cout << "Hp + 20" << std::endl;
}
};
class Bigshop : public Abstractshop
{
public:
void cost() override
{
std::cout << "cost 50$" << std::endl;
}
void get() override
{
std::cout << "Hp + 100" << std::endl;
}
};
在Factory.h中,定义了一个Factory类,代表工厂,通过creatshop()函数生产产品。为了实现多态,creatshop()函数返回Abstractshop*。
另外,还定义了一个类型为char的枚举类,用以选择不同型号的产品。
//Factory.h
#pragma once
#include "shop.h"
enum class Type : char { LITTLE, MIDDLE, BIG };
class Factory
{
public:
Factory() {
std::cout<<"工厂开工!!!."<<std::endl;
}
~Factory() {
std::cout<<"工厂停工!!!."<<std::endl;
}
Abstractshop* createshop(Type type)
{
Abstractshop* ptr = nullptr;
switch (type)
{
case Type::LITTLE:
std::cout<<"You buy a Little Shop." << std::endl;
ptr = new Littleshop;
break;
case Type::MIDDLE:
std::cout<<"You buy a Middle Shop." << std::endl;
ptr = new Middleshop;
break;
case Type::BIG:
std::cout<<"You buy a Big Shop." << std::endl;
ptr = new Bigshop;
break;
default:
break;
}
return ptr;
}
};
1 #include "Factory.h"
2
3 int main()
4 {
5 Factory* factory = new Factory;
6 Abstractshop* obj = factory->createshop(Type::MIDDLE);
7 obj->cost();
8 obj->get();
9
10 delete obj;
11 delete factory;
12
13 return 0;
14 }
简单工厂模式有个很明显缺点就是:不满足类的三大原则之一——开放-封闭原则。
开发封闭原则:软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。
假如我们要增加新商品类,可以通过抽象商品类派生(扩展)。但是工厂类就不得不修改,以增加对新商品类的选择。这就违背了设计类的原则。
工厂模式
在工厂模式我们将设计一个抽象工厂类。然后派生出只能生产某一具体产品的工厂。这相当于是把简单工厂模式中的工厂类拆分成了多个子工厂。每个子工厂只生产一种产品。
在这样的情况下, 如果想增加一个新商品,那么只需要在shop.h中派生一个新的商品类。对应的,在Factor.h中也得新派生一个新商品的工厂类。这样就不会违背开发-封闭原则了。
//Factory.h
#pragma once
#include "shop.h"
class AbstractFactory
{
public:
virtual ~AbsreactFactory() {}
virtual Abstractshop* createshop(){}
};
class LittleShop : public AbstractShop()
{
public:
LittleShop(){
std::cout<< "LittleShop 开业!!!"<<std::endl;
}
Abstractshop* createshop() override
{
std::cout<<"You buy a Littleshop."<<std::endl;
return new Littleshop;
}
~LitteShop(){
std::cout<< "littleShop 开业!!!"<<std::endl;
}
}
class MiddleShop : public AbstractShop()
{
public:
MiddleShop(){
std::cout<< "MiddleShop 开业!!!"<<std::endl;
}
Abstractshop* createshop() override
{
std::cout<<"You buy a Middleshop."<<std::endl;
return new Middleshop;
}
~MiddleShop(){
std::cout<< "MiddleShop 开业!!!"<<std::endl;
}
}
class BigShop : public AbstractShop()
{
public:
BigShop(){
std::cout<< "BigShop 开业!!!"<<std::endl;
}
Abstractshop* createshop() override
{
std::cout<<"You buy a Bigshop."<<std::endl;
return new Bigshop;
}
~BigShop(){
std::cout<< "BigShop 开业!!!"<<std::endl;
}
}
抽象工厂模式
抽象工厂模式可以理解为工厂模式的升级。工厂模式下,一个工厂只能产出一种商品。而抽象模式下,一个工厂可以产生商品的组合,或者说是可以生产多种商品。(工厂模式就是生产单品,抽象工厂模式是把不同商品组合,产出一个套餐)
//shop.h
#pragma once//(c++11 特性)相当于ifndef def endif
#include <iostream>
class Abstractshop
{
public:
virtual void cost(){}
virtual void get(){}
virtual ~Abstractshop(){}
};
class Littleshop : public Abstractshop
{
public:
Littleshop(){
std::cout<<"You get a littleshop, ";
this->cost();
}
~Littleshop(){
std::cout<<"You used a littleshop, ";
this->get();
}
void cost() override//(c++11 特性) 显式声明函数重写,禁止函数隐藏,这是为了实现多态
{
std::cout << "cost 10$" << std::endl;
}
void get() override
{
std::cout << "Hp + 10" << std::endl;
}
};
class Middleshop : public Abstractshop
{
public:
Middleshop(){
std::cout<<"You get a Midlleshop, ";
this->cost();
}
~Middleshop(){
std::cout<<"You used a Middleshop, ";
this->get();
}
void cost() override
{
std::cout << "cost 15$" << std::endl;
}
void get() override
{
std::cout << "Hp + 20" << std::endl;
}
};
class Bigshop : public Abstractshop
{
public:
Bigshop(){
std::cout<<"You get a Bigshop, ";
this->cost();
}
~Bigshop(){
std::cout<<"You used a Bigshop, ";
this->get();
}
void cost() override
{
std::cout << "cost 50$" << std::endl;
}
void get() override
{
std::cout << "Hp + 100" << std::endl;
}
};
//AbstractFactory.h
#pragma once
#include "shop.h"
#include "memory"
class Package//套餐类
{
private:
std::unique_ptr<Abstractshop> shop1_=NULL;
std::unique_ptr<Abstractshop> shop2_=NULL;
public:
Package(Abstractshop* shop1, Abstractshop* shop2):shop1_(shop1), shop2_(shop2){
std::cout<<"Your package is complete!"<<std::endl;
}
~Package(){
std::cout<<"Your Package is used!" <<std::endl;
}
};
class AbstractFactory//抽象工厂类
{
public:
virtual ~AbstractFactory() {}
virtual Package* createPackage()=0;//生产套餐
};
class ToLPackage : public AbstractFactory//经济套餐工厂
{
public:
Package* createPackage() override{
std::cout<< "你购买了经济套餐!!!"<<std::endl;
return new Package(new Littleshop, new Littleshop);
}
ToLPackage()
{
std::cout<< "经济套餐工厂开工!!!"<<std::endl;
}
~ToLPackage(){
std::cout<< "经济套餐工厂停工!!!"<<std::endl;
}
};
class ToMPackage : public AbstractFactory//小资套餐工厂
{
public:
Package* createPackage() override{
std::cout<< "你购买了小资套餐!!!"<<std::endl;
return new Package(new Middleshop, new Middleshop);
}
ToMPackage()
{
std::cout<< "小资套餐工厂开工!!!"<<std::endl;
}
~ToMPackage(){
std::cout<< "小资套餐工厂停工!!!"<<std::endl;
}
};
class ToBPackage : public AbstractFactory//富翁套餐工厂
{
public:
Package* createPackage() override{
std::cout<< "你购买了富翁套餐!!!"<<std::endl;
return new Package(new Bigshop, new Bigshop);
}
ToBPackage()
{
std::cout<< "富翁套餐工厂开工!!!"<<std::endl;
}
~ToBPackage(){
std::cout<< "富翁套餐工厂停工!!!"<<std::endl;
}
};
在主函数中,先创建了3个工厂。然后让L_factory生产了一个套餐产品pkg。
//main.cpp
#include "AbstractFactory.h"
#include <memory>
int main()
{
std::unique_ptr<AbstractFactory> L_factory (new ToLPackage());
std::unique_ptr<AbstractFactory> M_factory ( new ToMPackage() );
std::unique_ptr<AbstractFactory> B_factory ( new ToBPackage() );
std::unique_ptr<Package> pkg (L_factory->createPackage());
return 0;
}