基础理解
Q:为什么要用简单工厂 ?
A: 假设有一个卡车类,有 订单管理 、货物追踪 、费用计算 等等类 而且 十分依赖卡车类的数据结构,或直接调用其方法类,那么如果再想加入一个轮船类使用这些就会变得十分困难。
为了降低这种耦合,需要创建一个中间工厂类。所有产品(卡车类,轮船类)送进去加工,直接调用工厂类中产品的方法(订单管理,货物追踪这些方法)
![![[Pasted image 20240326210221.png|400]]](https://i-blog.csdnimg.cn/blog_migrate/c428cf7ff26b9e9ea49a4d604687b852.png)
注意点:
- 让所有产品都遵循同一接口。 该接口必须声明对所有产品都有用的方法。
- 适用于创建单个对象。其下没有包含更详细的种类
- 工厂里面要有清晰的对象创建方式,方便创建
UML 图
![![[Pasted image 20240330232456.png]]](https://i-blog.csdnimg.cn/blog_migrate/42f916d3fbafd6f0c475ceeb10456a7f.png)
样例代码
#include <iostream>
/**
* Product 接口声明了所有具体产品必须实现的操作。
*/
class Logistics
{
public:
virtual ~Product() {}
virtual std::string Operation() const = 0;
virtual std::string Calculate_Price() const = 0; // 添加 Calculate_Price 方法
};
/**
* 具体产品提供 Logistics 接口的各种实现。
*/
class RoadLogistics : public Logistics
{
public:
std::string Operation() const override
{
return "{RoadLogistics 的结果}";
}
std::string Calculate_Price() const override
{
return "100"; // 陆运的的价格计算
}
};
class SeaLogitics : public Logistics
{
public:
std::string Operation() const override
{
return "{SeaLogitics 的结果}";
}
std::string Calculate_Price() const override
{
return "150"; // 船运的的价格计算
}
};
/**
* Creator 类声明了工厂方法,应该返回一个 Product 类的对象。Creator 的子类通常提供此方法的实现。
*/
class Creator
{
public:
virtual ~Creator(){};
virtual Product *CreatProduct() const = 0;
};
/**
* 具体创建者覆盖工厂方法以改变生成的产品类型。
*/
class ConcreteCreator1 : public Creator
{
public:
Product *CreatProduct() const override
{
return new RoadLogistics();
}
};
class ConcreteCreator2 : public Creator
{
public:
Product *CreatProduct() const override
{
return new SeaLogitics();
}
};
/**
* 客户端代码通过具体创建者的实例(通过基础接口)进行操作。只要客户端继续通过基础接口与创建者交互,就可以传递任何创建者的子类。
*/
void ClientCode(const Creator &creator)
{
// 调用 CreatProduct 创建产品对象
Product *product = creator.CreatProduct();
// 使用 Operation 方法
std::cout << "Operation 结果: " << product->Operation() << std::endl;
// 使用 Calculate_Price 方法
std::cout << "价格: " << product->Calculate_Price() << std::endl;
delete product;
}
/**
* 应用程序根据配置或环境选择创建者的类型。
*/
int main()
{
std::cout << "App: 使用 ConcreteCreator1 启动。\n";
Creator *creator = new ConcreteCreator1();
ClientCode(*creator);
std::cout << std::endl;
std::cout << "App: 使用 ConcreteCreator2 启动。\n";
Creator *creator2 = new ConcreteCreator2();
ClientCode(*creator2);
delete creator;
delete creator2;
return 0;
}
与其他模式的联系
- 抽象工厂模式通常基于一组工厂方法, 但你也可以使用原型模式来生成这些类的方法。
使用原型模式生成一组相同的产品
- 你可以同时使用工厂方法和迭代器模式来让子类集合返回不同类型的迭代器, 并使得迭代器与集合相匹配。
额外创建一个迭代器工厂,让 子类集合 的工厂嵌套进去 首先创建子类 然后调用迭代器工厂
工厂模式的好处:
- 解耦合:工厂方法模式可以将产品的创建和使用解耦,客户端代码只需要关心产品接口和工厂接口,
- 代码复用:工厂方法模式可以提供一种统一的创建产品对象的方式,避免重复的代码
- 隐藏复杂逻辑:具体产品的创建逻辑被封装在具体工厂类中,客户端无需关心具体产品的创建细节
- 扩展性:通过添加新的具体工厂类和具体产品类,可以方便地扩展系统功能,符合开闭原则。不需要修改现有代码,只需新增对应的工厂类和产品类即可。
1489





