#C++设计模式:简单工厂模式与工厂模式
在软件开发中,**设计模式**是一套可重用的、最佳的实践方案,用于解决开发过程中经常遇到的设计问题。本文将介绍两种常用的设计模式:**简单工厂模式**和**工厂模式**,并分析它们的优缺点和适用场景。
1. 设计模式的三大基本原则
在开始讨论代码实现之前,首先介绍设计模式的三大基本原则:
1.1- 开闭原则(Open-Closed Principle):软件实体应对扩展开放、对修改关闭。即在不修改现有代码的基础上,通过增加新代码来扩展功能。
1.2- 单一职责原则(Single Responsibility Principle):每个类应只有一个引起变化的原因,即一个类只负责一项职责。
1.3- 依赖倒置原则(Dependency Inversion Principle):高层模块不应该依赖低层模块,二者都应该依赖于抽象;抽象不应该依赖细节,细节应该依赖抽象。
2. 简单工厂模式
**简单工厂模式**是工厂模式的一种变体。它的特点是使用一个工厂类,根据不同的参数创建不同的实例。它**不符合开闭原则**,因为如果需要添加新的产品类型,必须修改工厂类的代码。
2.1 简单工厂模式的代码实现
// 抽象基类 AbtractSmile
class AbtractSmile {
public:
virtual void transform() = 0; // 纯虚函数 //子类必须实现
virtual void ability() = 0; // 纯虚函数
virtual ~AbtractSmile() {} // 虚析构函数
};
// 派生类 SheepSmile
class SheepSmile : public AbtractSmile {
public:
void transform() {
cout << "sheep " << endl;
}
void ability() {
cout << "sheep ability" << endl;
}
};
// 派生类 BatSmile
class BatSmile : public AbtractSmile {
public:
void transform() {
cout << "bat " << endl;
}
void ability() {
cout << "bat ability" << endl;
}
};
// 枚举类型 MyType
enum MyType {
Sheep,
Bat,
Lion
};
// 工厂类 MyFactory
class MyFactory {
public:
AbtractSmile* createSmile(MyType type) {
AbtractSmile* ptr = nullptr;
switch (type) {
case Sheep:
ptr = new SheepSmile(); break; // 创建 SheepSmile 实例
case Bat:
ptr = new BatSmile(); break; // 创建 BatSmile 实例
default:
break;
}
return ptr;//返回父类指向子类的指针(多态)
}
};
int main() {
MyFactory* f = new MyFactory; // 创建工厂实例
AbtractSmile* s = f->createSmile(Bat); // 创建 BatSmile 实例,用父类对象指向子类,实现多态
s->transform(); // 调用对应子类 transform 函数
s->ability(); // 调用对应子类 ability 函数
return 0;
}
2.2 简单工厂模式的优缺点
- **优点**:实现简单,适用于产品种类固定的情况。
- **缺点**:不符合开闭原则。每次增加新产品时,都要修改 `MyFactory` 中的代码。
3. 工厂模式
工厂模式**是对简单工厂模式的进一步抽象。它将创建对象的逻辑进一步封装到独立的工厂类中,使得每个具体工厂类负责创建一种产品。这样做符合开闭原则和依赖倒置原则。
3.1 工厂模式的代码实现
class AbtractSmile //抽象类-父类
{
public:
virtual void transform() = 0;
virtual void ability() = 0;
virtual ~AbtractSmile() {} //实现多态时,需加入虚析构函数,子类就能完整析构
};
class SheepSmile : public AbtractSmile //子类
{
public:
void transform()
{
cout << "sheep " << endl;
}
void ability()
{
cout << "sheep ability" << endl;
}
};
class BatSmile : public AbtractSmile //子类
{
public:
void transform()
{
cout << "bat " << endl;
}
void ability()
{
cout << "bat ability" << endl;
}
};
class AbtractFactory //工厂 抽象类-父类
{
public:
virtual AbtractSmile* createSmile() = 0;
virtual ~AbtractFactory(){} //实现多态时,需加入虚析构函数,子类就能完整析构
};
class SheepFactory : public AbtractFactory//子类工厂
{
public:
AbtractSmile* createSmile() override //重写父类方法
{
return new SheepSmile(); //返回对应子类
}
~SheepFactory() //子类析构(多态)
{
cout << "SheepFactory 被析构..." << endl;
}
};
class BatFactory : public AbtractFactory
{
public:
AbtractSmile* createSmile() override
{
return new BatSmile();
}
~BatFactory()
{
cout << "BatFactory 被析构..." << endl;
}
};
int main()
{
AbtractFactory* f = new SheepFactory();//使用父类工厂指向子类工厂
AbtractSmile* obj = f->createSmile();//创建对应子类对象,并使用其父类指针指向
obj->transform();//执行对应子类函数
obj->ability();//执行对应子类函数
delete obj;//触发析构
delete f;//触发析构
return 0;
}
3.2 工厂模式的优缺点
- **优点**:符合开闭原则和依赖倒置原则,每个具体工厂类负责创建一个产品类型,可以轻松添加新的工厂类,不需要修改现有代码。
- **缺点**:需要为每种产品创建一个具体工厂类,增加了代码量。
4.简单工厂模式和工厂模式的UML图
4.1简单工厂模式:
4.2工厂模式:
5. 总结
- **简单工厂模式**:适合产品种类较少的情况,但不符合开闭原则,扩展性较差。
- **工厂模式**:符合开闭原则和依赖倒置原则,更适合需要扩展产品类型的场景。
通过对比两种工厂模式,我们可以看到,**工厂模式**是一个更加灵活和可扩展的设计,符合设计模式的基本原则。