设计模式--简单工厂模式
Posted Jqivin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式--简单工厂模式相关的知识,希望对你有一定的参考价值。
简单工厂模式介绍
简单工厂模式并不属于GoF 23个经典设计模式。它的设计思想很简单。
首先,我们定义不同的具体产品类
来封装不同类型的对象的相关代码。然后将这些具体产品类中的共同部分提取后封装到一个抽象产品类
中。每一个具体产品类都是抽象产品类的子类。然后我们定义一个工厂类
,里面封装一个创建不同产品的工厂方法(静态方法),使客户端可以传入工厂类不同的参数来创建不同的产品。
客户端想要创建 产品只需要给工厂类的静态方法提供相应的参数就可以了。
有以下几种角色:
●Factory(工厂角色)
:工厂角色即工厂类,它是简单工厂模式的核心,负责实现创建所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需的产品对象;在工厂类中提供了静态的工厂方法factoryMethod(),它的返回类型为抽象产品类型Product。
●Product(抽象产品角色)
:它是工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个通用的工厂方法,因为所有创建的具体产品对象都是其子类对象。
● ConcreteProduct(具体产品角色)
:它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法。
在简单工厂模式中,客户端通过工厂类来创建一个产品类的实例,而无须直接使用new关键字来创建对象,它是工厂模式家族中最简单的一员。
用简单工厂模式生产Audi和Benz汽车。
代码如下:
//抽象产品类
class Car
{
public:
Car(){}
virtual ~Car() {}
//所有产品的公共业务方法...
//产品的抽象方法,在子类中实现
virtual void show() = 0;
};
//具体产品类
class Audi :public Car
{
public:
Audi(){ cout << "construct Audi car" << endl; }
~Audi(){ cout << "destory Audi car" << endl; }
void show() { cout << "this is a Audi car" << endl; }
};
class Benz :public Car
{
public:
Benz() { cout << "construct Benz car" << endl; }
~Benz() { cout << "destory Benz car" << endl; }
void show() { cout << "this is a Benz car" << endl; }
};
//工厂
class Factory
{
public:
static Car* getCar(const string& name)
{
if (name == "Audi")
return new Audi();
else if (name == "Benz")
return new Benz();
else
{
return nullptr;
}
}
};
//客户端
int main()
{
unique_ptr<Factory> fa(new Factory);
unique_ptr<Car> ad(fa->getCar("Audi"));
unique_ptr<Car> bz(fa->getCar("Benz"));
ad->show();
bz->show();
return 0;
}
结果:
也可以改一下代码,当没有这个类型的车的时候,抛出异常。
class NoCar
{
public:
NoCar(const string& name) { cout << "don't have "<<name <<" car" << endl; }
~NoCar() { cout << "bye error" << endl; }
};
//工厂
class Factory
{
public:
static Car* getCar(const string& name)
{
if (name == "Audi")
return new Audi();
else if (name == "Benz")
return new Benz();
else
{
//return nullptr;
throw NoCar(name);
}
}
};
//客户端
int main()try
{
unique_ptr<Factory> fa(new Factory);
unique_ptr<Car> ad(fa->getCar("Audi"));
ad->show();
unique_ptr<Car> bm(fa->getCar("BMW"));
bm->show();
cout << "hello" << endl;
return 0;
}
catch (...) //catch(NoCar&) 只捕获NoCar异常
{
cout << "error" << endl;
}
结果:捕获异常之后就不在进入主函数了(没有输出hello)。
总结
1. 优点
(1)包含必要的逻辑判断,可以根据客户端提供的参数来决定创建何种产品。
(2) 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以在一定程度减少使用者的记忆量
2. 缺点
(1)适合少量种类的产品的创建。产品种类过多会造成类过多。而且工厂类中的静态方法也会做更多的if条件判断,导致工厂类的职责过多。
(2)当系统中需要引入新产品时,由于静态工厂方法通过所传入参数的不同来创建不同的产品,这必定要修改工厂类的源代码,将违背“开闭原则”。
(3)所有的产品都由同一个工厂创建,工厂类职责较重,业务逻辑较为复杂,具体产品与工厂类之间的耦合度高,严重影响了系统的灵活性和扩展性。
开闭原则
:一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
3.适合场景
(1) 工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
(2) 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。
异常的处理
以上是关于设计模式--简单工厂模式的主要内容,如果未能解决你的问题,请参考以下文章