目录
3. 工厂模式
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。工厂模式作为一种创建模式,一般在创建复杂对象时,考虑使用;在创建简单对象时,建议直接new完成一个实例对象的创建。
3.1 简单工厂模式
主要特点是需要在工厂类中做判断,从而创造相应的产品,当增加新产品时,需要修改工厂类。使用简单工厂模式,我们只需要知道具体的产品型号就可以创建一个产品。
缺点:
1. 工厂类集中了所有产品类的创建逻辑,如果产品量较大,会使得工厂类变的非常臃肿。
2. 就是要增加新的核类型时,就需要修改工厂类。这就违反了开放封闭原则:对扩展开放,对修改关闭。
/*
关键代码:创建过程在工厂类中完成。
*/
#include <iostream>
using namespace std;
//定义产品类型信息
typedef enum
{
Tank_Type_56,
Tank_Type_96,
Tank_Type_Num
}Tank_Type;
//抽象产品类
class Tank
{
public:
virtual const string& type() = 0;
};
//具体的产品类
class Tank56 : public Tank
{
public:
Tank56():Tank(),m_strType("Tank56")
{
}
const string& type() override
{
cout << m_strType.data() << endl;
return m_strType;
}
private:
string m_strType;
};
//具体的产品类
class Tank96 : public Tank
{
public:
Tank96():Tank(),m_strType("Tank96")
{
}
const string& type() override
{
cout << m_strType.data() << endl;
return m_strType;
}
private:
string m_strType;
};
//工厂类
class TankFactory
{
public:
//根据产品信息创建具体的产品类实例,返回一个抽象产品类
Tank* createTank(Tank_Type type)
{
switch(type)
{
case Tank_Type_56:
return new Tank56();
case Tank_Type_96:
return new Tank96();
default:
return nullptr;
}
}
};
int main()
{
TankFactory* factory = new TankFactory();
Tank* tank56 = factory->createTank(Tank_Type_56);
tank56->type();
Tank* tank96 = factory->createTank(Tank_Type_96);
tank96->type();
delete tank96;
tank96 = nullptr;
delete tank56;
tank56 = nullptr;
delete factory;
factory = nullptr;
return 0;
}
3.1.1 例子2
有一家生产处理器核的厂家,它只有一个工厂,能够生产两种型号的处理器核。客户需要什么样的处理器核,一定要显示地告诉生产工厂。
enum CTYPE
{
COREA,
COREB
};
class SingleCore
{
public:
virtual void Show() = 0;
};
//单核A
class SingleCoreA: public SingleCore
{
public:
void Show() { cout<<"SingleCore A"<<endl; }
};
//单核B
class SingleCoreB: public SingleCore
{
public:
void Show() { cout<<"SingleCore B"<<endl; }
};
//唯一的工厂,可以生产两种型号的处理器核,在内部判断
class Factory
{
public:
SingleCore* CreateSingleCore(enum CTYPE ctype)
{
if(ctype == COREA) //工厂内部判断
return new SingleCoreA(); //生产核A
else if(ctype == COREB)
return new SingleCoreB(); //生产核B
else
return NULL;
}
};
3.2 工厂方法模式
定义一个创建对象的接口,其子类去具体现实这个接口以完成具体的创建工作。如果需要增加新的产品类,只需要扩展一个相应的工厂类即可。
缺点:产品类数据较多时,需要实现大量的工厂类,这无疑增加了代码量。
/*
关键代码:创建过程在其子类执行。
*/
#include <iostream>
using namespace std;
//产品抽象类
class Tank
{
public:
virtual const string& type() = 0;
};
//具体的产品类
class Tank56 : public Tank
{
public:
Tank56():Tank(),m_strType("Tank56")
{
}
const string& type() override
{
cout << m_strType.data() << endl;
return m_strType;
}
private:
string m_strType;
};
//具体的产品类
class Tank96 : public Tank
{
public:
Tank96():Tank(),m_strType("Tank96")
{
}
const string& type() override
{
cout << m_strType.data() << endl;
return m_strType;
}
private:
string m_strType;
};
//抽象工厂类,提供一个创建接口
class TankFactory
{
public:
//提供创建产品实例的接口,返回抽象产品类
virtual Tank* createTank() = 0;
};
//具体的创建工厂类,使用抽象工厂类提供的接口,去创建具体的产品实例
class Tank56Factory : public TankFactory
{
public:
Tank* createTank() override
{
return new Tank56();
}
};
//具体的创建工厂类,使用抽象工厂类提供的接口,去创建具体的产品实例
class Tank96Factory : public TankFactory
{
public:
Tank* createTank() override
{
return new Tank96();
}
};
int main()
{
TankFactory* factory56 = new Tank56Factory();
Tank* tank56 = factory56->createTank();
tank56->type();
TankFactory* factory96 = new Tank96Factory();
Tank* tank96 = factory96->createTank();
tank96->type();
delete tank96;
tank96 = nullptr;
delete factory96;
factory96 = nullptr;
delete tank56;
tank56 = nullptr;
delete factory56;
factory56 = nullptr;
return 0;
}
3.2.1 举例2:
接上面的举例2,这家生产处理器核的产家赚了不少钱,于是决定再开设一个工厂专门用来生产B型号的单核,而原来的工厂专门用来生产A型号的单核。这时,客户要做的是找好工厂,比如要A型号的核,就找A工厂要;否则找B工厂要,不再需要告诉工厂具体要什么型号的处理器核了。
class SingleCore
{
public:
virtual void Show() = 0;
};
//单核A
class SingleCoreA: public SingleCore
{
public:
void Show() { cout<<"SingleCore A"<<endl; }
};
//单核B
class SingleCoreB: public SingleCore
{
public:
void Show() { cout<<"SingleCore B"<<endl; }
};
class Factory
{
public:
virtual SingleCore* CreateSingleCore() = 0;
};
//生产A核的工厂
class FactoryA: public Factory
{
public:
SingleCoreA* CreateSingleCore() { return new SingleCoreA; }
};
//生产B核的工厂
class FactoryB: public Factory
{
public:
SingleCoreB* CreateSingleCore() { return new SingleCoreB; }
};
3.3 抽象工厂模式
抽象工厂模式提供创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
当存在多个产品系列,而客户端只使用一个系列的产品时,可以考虑使用抽象工厂模式。
缺点:当增加一个新系列的产品时,不仅需要现实具体的产品类,还需要增加一个新的创建接口,扩展相对困难。
/*
2 * 关键代码:在一个工厂里聚合多个同类产品。
3 * 以下代码以白色衣服和黑色衣服为例,白色衣服为一个产品系列,黑色衣服为一个产品系列。白色上衣搭配白色裤子, 黑色上衣搭配黑色裤字。每个系列的衣服由一个对应的工厂创建,这样一个工厂创建的衣服能保证衣服为同一个系列。
*/
//抽象上衣类
class Coat
{
public:
virtual const string& color() = 0;
};
//黑色上衣类
class BlackCoat : public Coat
{
public:
BlackCoat():Coat(),m_strColor("Black Coat")
{
}
const string& color() override
{
cout << m_strColor.data() << endl;
return m_strColor;
}
private:
string m_strColor;
};
//白色上衣类
class WhiteCoat : public Coat
{
public:
WhiteCoat():Coat(),m_strColor("White Coat")
{
}
const string& color() override
{
cout << m_strColor.data() << endl;
return m_strColor;
}
private:
string m_strColor;
};
//抽象裤子类
class Pants
{
public:
virtual const string& color() = 0;
};
//黑色裤子类
class BlackPants : public Pants
{
public:
BlackPants():Pants(),m_strColor("Black Pants")
{
}
const string& color() override
{
cout << m_strColor.data() << endl;
return m_strColor;
}
private:
string m_strColor;
};
//白色裤子类
class WhitePants : public Pants
{
public:
WhitePants():Pants(),m_strColor("White Pants")
{
}
const string& color() override
{
cout << m_strColor.data() << endl;
return m_strColor;
}
private:
string m_strColor;
};
//抽象工厂类,提供衣服创建接口
class Factory
{
public:
//上衣创建接口,返回抽象上衣类
virtual Coat* createCoat() = 0;
//裤子创建接口,返回抽象裤子类
virtual Pants* createPants() = 0;
};
//创建白色衣服的工厂类,具体实现创建白色上衣和白色裤子的接口
class WhiteFactory : public Factory
{
public:
Coat* createCoat() override
{
return new WhiteCoat();
}
Pants* createPants() override
{
return new WhitePants();
}
};
//创建黑色衣服的工厂类,具体实现创建黑色上衣和白色裤子的接口
class BlackFactory : public Factory
{
Coat* createCoat() override
{
return new BlackCoat();
}
Pants* createPants() override
{
return new BlackPants();
}
};
3.3.1 举例2
还是举这个例子,这家公司的技术不断进步,不仅可以生产单核处理器,也能生产多核处理器。现在简单工厂模式和工厂方法模式都鞭长莫及。抽象工厂模式登场了。它的定义为提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。具体这样应用,这家公司还是开设两个工厂,一个专门用来生产A型号的单核多核处理器,而另一个工厂专门用来生产B型号的单核多核处理器,下面给出实现的代码:
//单核
class SingleCore
{
public:
virtual void Show() = 0;
};
class SingleCoreA: public SingleCore
{
public:
void Show() { cout<<"Single Core A"<<endl; }
};
class SingleCoreB :public SingleCore
{
public:
void Show() { cout<<"Single Core B"<<endl; }
};
//多核
class MultiCore
{
public:
virtual void Show() = 0;
};
class MultiCoreA : public MultiCore
{
public:
void Show() { cout<<"Multi Core A"<<endl; }
};
class MultiCoreB : public MultiCore
{
public:
void Show() { cout<<"Multi Core B"<<endl; }
};
//工厂
class CoreFactory
{
public:
virtual SingleCore* CreateSingleCore() = 0;
virtual MultiCore* CreateMultiCore() = 0;
};
//工厂A,专门用来生产A型号的处理器
class FactoryA :public CoreFactory
{
public:
SingleCore* CreateSingleCore() { return new SingleCoreA(); }
MultiCore* CreateMultiCore() { return new MultiCoreA(); }
};
//工厂B,专门用来生产B型号的处理器
class FactoryB : public CoreFactory
{
public:
SingleCore* CreateSingleCore() { return new SingleCoreB(); }
MultiCore* CreateMultiCore() { return new MultiCoreB(); }
};
3.4 模式UML图
利用Rational Rose 2003软件,给出三种工厂模式的UML图,加深印象。
简单工厂模式的UML图:
工厂方法的UML图:
抽象工厂模式的UML图:
参考文档:https://blog.youkuaiyun.com/wuzhekai1985/article/details/6660462