当前位置: 首页 > news >正文

简单工厂模式 - 实践

简单工厂模式(Simple Factory Pattern)

简单工厂模式(又称静态工厂模式)是一种创建型设计模式,它通过一个工厂类来封装对象的创建逻辑,客户端无需直接实例化具体类,而是通过工厂类获取所需对象。

1.类图结构

简单工厂类图

2.关键角色

角色说明
Client客户端,一个或多个,调用SimpleFactorycreateProduct()创建Product
SimpleFactory工厂类,根据Client的输入创建具体的 Product
Product抽象产品,定义产品行为,可以是抽象类或接口类,取决于实际场景
ConcreteProductA ConcreteProductB具体产品,继承或实现 Product

3. 代码示例

3.1 定义抽象产品

// 抽象形状类
class IShape
{
public:
virtual ~IShape(
) =
default
;
virtual
double area(
)
const = 0
;
virtual
void draw(
)
const = 0
;
}
;

3.2 定义具体产品

// 具体形状类 - 圆形
constexpr
double M_PI = 3.14
;
class Circle : public IShape
{
public:
explicit Circle(std::initializer_list<
double> args)
{
if (args.size(
) == 1
) {
auto iter = args.begin(
)
;
radius = *iter;
}
if (radius <= 0
) {
throw std::invalid_argument("Circle radius must be positive"
)
;
}
}
double area(
)
const
override
{
return M_PI * radius * radius;
}
void draw(
)
const
override
{
std::cout <<
"Drawing a circle with radius " << radius
<<
" and area " <<
area(
) << std::endl;
}
private:
double radius;
}
;
// 具体形状类 - 矩形
class Rectangle : public IShape
{
public:
Rectangle(
double w,
double h) : width(w)
, height(h) {
}
Rectangle(std::initializer_list<
double> args)
{
if (args.size(
) == 2
)
{
auto iter = args.begin(
)
;
width = *iter++
;
height = *iter;
}
if (width <= 0 || height <= 0
)
throw std::invalid_argument("Rectangle dimensions must be positive"
)
;
}
double area(
)
const
override {
return width * height;
}
void draw(
)
const
override {
std::cout <<
"Drawing a rectangle " << width <<
"x" << height
<<
" with area " <<
area(
) << std::endl;
}
private:
double width, height;
}
;
// 具体形状类 - 三角形
class Triangle : public IShape
{
public:
Triangle(std::initializer_list<
double> args)
{
if (args.size(
) == 3
)
{
auto iter = args.begin(
)
;
a = *iter++
;
b = *iter++
;
c = *iter;
}
// 验证是否为有效三角形
if (a + b <= c || a + c <= b || b + c <= a) {
throw std::invalid_argument("Invalid triangle sides"
)
;
}
}
double area(
)
const
override {
// 使用海伦公式计算面积
double s = (a + b + c) / 2
;
return sqrt(s * (s - a) * (s - b) * (s - c)
)
;
}
void draw(
)
const
override {
std::cout <<
"Drawing a triangle with sides " << a <<
", " << b <<
", " << c
<<
" and area " <<
area(
) << std::endl;
}
private:
double a, b, c;
}
;

3.3 定义简单工厂

// 形状工厂类
class ShapeFactory
{
public:
static std::unique_ptr<IShape>createShape(const std::string& type, std::initializer_list<double> args){if (type == "circle")return std::make_unique<Circle>(args);elseif (type == "rectangle")return std::make_unique<Rectangle>(args);elseif (type == "triangle")return std::make_unique<Triangle>(args);throw std::invalid_argument("Unknown shape type: " + type);}};

3.4 客户端调用

#
include <cmath>#include <iostream>#include <memory>#include <stdexcept>#include <string>int main(){try{// 创建圆形auto circle = ShapeFactory::createShape("circle", {5.0});circle->draw();// 创建矩形auto rectangle = ShapeFactory::createShape("rectangle", {4.0, 6.0});rectangle->draw();// 创建三角形auto triangle = ShapeFactory::createShape("triangle", {3.0, 4.0, 5.0});triangle->draw();// 尝试创建无效形状会抛出异常auto invalidCircle = ShapeFactory::createShape("circle", {-1.0});auto invalidTriangle = ShapeFactory::createShape("triangle", {1.0, 2.0, 5.0});}catch (const std::exception& e){std::cerr <<"Error: " << e.what() << std::endl;}return 1;}

4. 特点

✅ 优点


❌ 缺点


4. 对比其他工厂模式

模式特点适用场景
简单工厂一个工厂类,通过 if-else 创建不同产品产品种类少,变化少
工厂方法每个产品对应一个工厂,符合开闭原则产品种类多,可能扩展
抽象工厂生产多个产品族(如不同风格的UI组件)需要创建一组相关对象

5. 适用场景

6. 变体:静态工厂方法

如果工厂方法定义为 static,则称为静态工厂(如 SimpleFactory::createProduct())。
优点:无需实例化工厂类,直接调用。
缺点:无法通过继承改变创建方法的逻辑。

7. 总结

http://www.jsqmd.com/news/9582/

相关文章:

  • 1.springmvc基础入门(一) - 详解
  • 爱,在行动中生长,我们因爱而变得辽阔——《岛上书店》读后感
  • Ubuntu 下同名文件替换后编译链接到旧内容的现象分析 - 实践
  • Luogu P14007 「florr IO Round 1」查询游戏 题解 [ 蓝 ] [ 交互 ]
  • RK3588和FPGA桥片之间IO电平信号概率性不能通信原因 - 实践
  • 稀缺计算资源如何塑造机器学习优化专家
  • 优雅的合并GIT分支
  • 实用指南:豆瓣图书评论数据分析与可视化
  • 完整教程:Excel to JSON 插件 2.4.0 版本更新
  • Ai元人文:人文逻辑与规则逻辑的统一
  • 《二千年间》在线阅读
  • 蒟蒻的第一篇随笔
  • 实用指南:Java 单例模式详解
  • oppoR9m刷Linux系统: 安装MTK USB VCOM驱动
  • 数据结构与算法学习笔记(Acwing 提高课)----动态规划树形DP - 详解
  • 可视化大屏工具对比:GoView、DataRoom、积木JimuBI、Metabase、DataEase、Apache Superset 与 Grafana - 实践
  • [特殊字符] FFmpeg 学习笔记 - 详解
  • .NET周刊【9月第3期 2025-09-21】
  • 通过实验直观理解神经网络:ReLU网络与几何解释
  • CCPC2023哈尔滨 游记(VP)
  • 2025教练技术行业深度剖析:目标人群、费用与品牌选择
  • 统计备注
  • 单例模式的类和静态方法的类的区别和使用场景 - 指南
  • LGP9871 [NOIP 2023] 天天爱打卡 学习笔记
  • 【OpenGL ES】Windows上OpenGL环境搭建
  • 虚拟现实教育终端科技方案——基于EFISH-SCB-RK3588的全场景国产化替代
  • 免费开源Umi-OCR,离线采用,批量精准!
  • 2025连接器厂家权威推荐榜:防水/m12防水/m8/防水3芯/防水t型三通/防水线束线缆/防水包胶连接器实力制造与创新技术深度解析
  • STM32外部中断(EXTI)以及旋转编码器的简介 - 指南
  • 神经网络中的梯度消失与梯度爆炸 - 实践