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

【设计模式】创建者模式——1.简单工厂模式

一、针对类的简单工厂

在开发过程中,如果想要创建一个对象,我们最直接的办法就是直接new出来它,就像下面这样↓

// 声明一个Circle类
class Circle
{
}
// 创建一个circle对象
var circle = new Circle();

这样当然是没有任何问题的。但是,如果Circle类有很多属性和字段需要初始化,那么简单的new Circle()就满足不了我们的要求了,我们就需要为Circle类提供一个有参构造函数,或者在new出一个空白的Circle对象之后,对其需要初始化的属性进行赋值,就像下面那样↓

// 声明一个带有多个参数的Circle类
class Circle
{// 名称public string Name { get; set; }// 面积public string Area { get; set; }// 周长public string Perimeter { get; set; }public Circle(string name, string area, string perimeter){Name = name;Area = area;Perimeter = perimeter;}
}
// 创建Circle对象并初始化// 方法1:使用有参构造
var circle1 = new Circle("圆形1", 30, 50);
// 方法2:使用无参构造+属性单独初始化
var circle2 = new Circle();
circle2.Name = "圆形2";
circle2.Area = 70;
circle2.Perimeter = 80;

这样其实就看出端倪了,如果在我当前项目中,我的Circle类就是会被初始化成Name = "圆形";Area = 70;Perimeter = 80;的情况呢,我管这种情况叫A类型Circle,那我直接给我的Circle类的属性设置默认值不就好了吗?省的我在创建Circle的地方每次都要写这三个参数的值,就像下面那样↓

// 默认使用A方案,为Circle的属性赋默认值
class Circle
{// 名称public string Name { get; set; } = "圆形";// 面积public int Area { get; set; } = 70;// 周长public int Perimeter { get; set; } = 80;public Circle(string name, int area, int perimeter){Name = name;Area = area;Perimeter = perimeter;}
}

这样确实很省心,每次都能输出一个初始化好的Circle对象,但是,如果后面业务变动,你的Circle对象在某些情况下需要初始化为Name = "大圆形";Area = 120;Perimeter = 150;呢?这时候原本的A类型Circle就不能直接用了,但是你肯定会说,这有何难?我不在Circle类中初始化属性了,我单独写一个类,就叫CircleFactory,由它来负责Circle对象的创建工作,我给它什么要求,它就给我new一个什么样的Circle对象返回给我好了,就像下面那样↓

// Circle工厂
class CircleFactory
{public static Circle CreateCircle(string type){if (type == "A"){var circleA = new Circle("圆形", 70, 80);return circleA;}else if (type == "B"){var circleB = new Circle("大圆形", 120, 150);return circleB;}else{return null;}}
} 

而我在调用时,仅需传递给工厂类,我要哪个型号的Circle对象即可,这大大简化了调用处的代码↓

// 调用Circle工厂,让Circle工厂来初始化我的Circle类,我只提供我需要A还是B
var circleA = CircleFactory.CreateCircle("A");

恭喜,你已经学会了简单工厂模式,上文描述的就是简单工厂模式的应用场景之一,将某个类的有限的初始化情况封装到工厂类中,通过调用工厂类的创建方法,给方法传参,来获取对应的初始化好的对象,简化调用处的代码。其UML图如下↓

二、针对接口的简单工厂

上文的代码是针对一个类的情况,如果是不同的类,但是这些类都实现了某个接口,也可以使用该方式来将创建对象的工作交给工厂类,就像下面这样↓

// 定义IShape接口
interface IShape
{// 名称public string Name { get; set; }// 面积public int Area { get; set; }// 周长public int Perimeter { get; set; }
}
// 定义Circle类,实现IShape接口
class Circle : IShape
{public string Name { get; set; }public int Area { get; set; }public int Perimeter { get; set; }
}
// 定义Rectangle类,实现IShape接口
class Rectangle : IShape
{public string Name { get; set; }public int Area { get; set; }public int Perimeter { get; set; }
}
// Shape工厂类
class ShapeFactory
{public static IShape CreateShape(string type){if (type == "circle"){var circle = new Circle();circle.Name = "圆形";circle.Area = 70;circle.Perimeter = 80;return circle;}else if (type == "rectangle"){var rectangle = new Rectangle();rectangle.Name = "矩形";rectangle.Area = 120;rectangle.Perimeter = 150;return rectangle;}else{return null;}}
}
// 调用Shape工厂,按需获取想要的对象
var circle = ShapeFactory.CreateShape("circle");
var rectangle = ShapeFactory.CreateShape("rectangle");

这就是简单工厂方法中的另外一种情况,其UML图如下↓

总结

简单工厂模式,是为了在创建需要初始化属性的对象时,无需调用者关心初始化的细节,把初始化的逻辑封装到工厂类中,统一管理和调用即可。

好处:

  1. 创建对象时,不需要关心创建对象的具体细节,例如初始化某个属性等等,只需要提供预设的参数即可

缺点:

  1. 如果需要创建的对象有很多,那么工厂类就会变得非常庞大,该类的职责就不太清晰
  2. 如果需要支持新的对象,则需要修改工厂类,违反开闭原则(对扩展开放,对修改关闭)
http://www.sczhlp.com/news/1343/

相关文章:

  • 智谱 GLM-4.5 也支持了Claude Code
  • 做题记录
  • 若依
  • Rust 性能优化秘籍:write! 宏让字符串构建提速 75%
  • 基于文件对比的技术写作内容碎片统一与上下文还原方法论
  • Rust 编译优化指南:如何让你的代码更小更快?
  • Windows下CMake安装及环境变量配置
  • Rust 字节处理入门指南:掌握 Vec、Cow 和零拷贝技术
  • 408-OS之阻塞IO和非阻塞IO
  • Python中字符串前“b”,“r”,“u”,“f”的作用
  • (个人思考) 直接使用GE,不用Ability
  • goethereum-地址检查 - Charlie
  • js高级第三天
  • 无需重训练即可教语音识别器学习新词
  • llama.cpp编译过程中的cmake版本问题 - Luna
  • 如何高效使用Cursor AI编程助手提升开发效率 | 完整配置与使用指南
  • WPF MVVM 入门学习笔记:从零开始理解 CommunityToolkit 与 ObservableObject 详解
  • 为所有人提供TSC频率:更精准的性能分析与基准测试
  • 第二十四天
  • Js 内存管理和闭包
  • js高级第二天
  • 双向循环链表完整实现与详解
  • JAVA学习
  • CSS 线性渐变
  • VMware ESXi 8.0U3g 发布 - 领先的裸机 Hypervisor
  • 装机软件记录
  • day3_javascript1
  • day4_javascript2
  • 电化学
  • 亚马逊AutoML论文获最佳论文奖