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

漫谈设计模式 [2]:工厂方法模式

引导性开场

菜鸟:老鸟,我在项目中遇到一个问题。每当需要创建对象时,我都直接使用类的构造函数,但随着项目复杂度的增加,这种方法变得越来越不可维护。你有什么建议吗?

老鸟:你提到的问题很常见。直接使用构造函数在简单场景下还行,但在复杂项目中会导致代码耦合度高、维护困难。你听说过工厂方法模式吗?

菜鸟:工厂方法模式?好像听过,但不太了解具体是什么。

渐进式介绍概念

老鸟:简单来说,工厂方法模式是一种创建对象的设计模式。它将对象的创建过程封装在一个工厂类中,而不是在代码中直接使用构造函数。举个生活中的例子,想象你去了一家餐馆点餐。你不会亲自去厨房做饭,而是告诉服务员你要什么,然后服务员帮你把饭菜准备好。这就类似于工厂方法模式。

菜鸟:哦,有点明白了。也就是说,工厂方法模式可以帮我们把对象的创建过程封装起来,对吧?

老鸟:没错!它的核心思想就是将对象的创建延迟到子类中,让子类决定要创建的对象类型。

Python代码示例,逐步展开

菜鸟:那我们用代码来看看吧。

老鸟:好的,先从一个简单的例子开始。假设我们有一个 Product 类和它的两个子类 ConcreteProductAConcreteProductB

class Product:def operation(self):passclass ConcreteProductA(Product):def operation(self):return "Result of ConcreteProductA"class ConcreteProductB(Product):def operation(self):return "Result of ConcreteProductB"

菜鸟:看起来很简单。那我们怎么用工厂方法模式来创建这些对象呢?

老鸟:首先,我们定义一个工厂基类 Creator,它有一个创建产品的方法 create_product。然后,我们定义具体的工厂子类 ConcreteCreatorAConcreteCreatorB,它们分别创建 ConcreteProductAConcreteProductB

class Creator:def create_product(self):passclass ConcreteCreatorA(Creator):def create_product(self):return ConcreteProductA()class ConcreteCreatorB(Creator):def create_product(self):return ConcreteProductB()

菜鸟:哦,我明白了。这样我们就可以通过工厂子类来创建不同的产品对象了。

老鸟:没错。来看看完整的例子。

# 产品类及其子类
class Product:def operation(self):passclass ConcreteProductA(Product):def operation(self):return "Result of ConcreteProductA"class ConcreteProductB(Product):def operation(self):return "Result of ConcreteProductB"# 工厂基类及其子类
class Creator:def create_product(self):passclass ConcreteCreatorA(Creator):def create_product(self):return ConcreteProductA()class ConcreteCreatorB(Creator):def create_product(self):return ConcreteProductB()# 客户端代码
def client_code(creator: Creator):product = creator.create_product()print(f"Client: {product.operation()}")if __name__ == "__main__":print("App: Launched with ConcreteCreatorA.")client_code(ConcreteCreatorA())print("App: Launched with ConcreteCreatorB.")client_code(ConcreteCreatorB())

菜鸟:这很有趣。但是,直接实例化工厂子类和直接使用构造函数有何区别呢?

问题与反思

老鸟:这是个好问题。直接使用构造函数时,客户端代码依赖于具体类,这会导致代码耦合度高。而使用工厂方法模式,客户端代码依赖于抽象的工厂类,具体的产品创建逻辑被封装在工厂子类中,这样可以降低代码的耦合度,提高可维护性。

菜鸟:明白了。这样当我们需要添加新产品时,只需要添加新的工厂子类和产品子类,而无需修改客户端代码。

老鸟:正是如此。

优势与适用场景

老鸟:工厂方法模式的优势在于:

  1. 降低耦合度:客户端代码依赖于抽象的工厂类,而不是具体的产品类。
  2. 提高可扩展性:添加新产品时,只需要添加新的工厂子类和产品子类,无需修改现有代码。
  3. 遵循开闭原则:扩展新的功能时,不需要修改现有代码,减少了错误风险。

菜鸟:那它适用于哪些场景呢?

老鸟:工厂方法模式适用于以下场景:

  1. 当一个类不知道它所需要的对象的类时
  2. 当一个类希望由其子类来指定创建的对象时
  3. 当类将创建对象的职责委托给多个帮助子类中的某一个时,并希望将哪一个子类是代理者这一信息局部化时

常见误区与优化建议

老鸟:不过,使用工厂方法模式时也要注意一些常见误区:

  1. 滥用模式:工厂方法模式适用于特定场景,不要为了使用而使用。
  2. 复杂性增加:对于简单对象创建,不必使用工厂方法模式,避免不必要的复杂性。

菜鸟:明白了,那有没有什么优化建议呢?

老鸟:优化建议包括:

  1. 明确需求:在决定使用工厂方法模式前,明确你的需求和问题。
  2. 结合其他模式:有时可以结合其他设计模式,如抽象工厂模式来进一步优化设计。

总结与延伸阅读

老鸟:今天我们讨论了工厂方法模式,包括它的定义、优势、适用场景以及常见误区。希望通过这些内容,你对工厂方法模式有了更深的理解。

菜鸟:非常感谢,老鸟!我学到了很多。

老鸟:不客气。如果你感兴趣,接下来可以学习一下其他设计模式,如单例模式和抽象工厂模式。推荐阅读《设计模式:可复用面向对象软件的基础》这本书,对理解设计模式非常有帮助。

菜鸟:好的,我会去看看这本书。谢谢你的指导!

老鸟:祝你学习愉快!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 第145天:内网安全-Linux权限维持Rootkit后门Strace监控Alias别名Cron定时任务
  • 在这12种场景下会使Spring事务失效--注意防范
  • RestTemplate服务调用
  • Qt C++ Udp相关知识学习(一)
  • React 通用后台管理项目
  • 使用paddlerocr识别固定颜色验证码
  • Spring Boot实现发QQ邮件
  • 算法day23| 93.复原IP地址、78.子集、90.子集II
  • python第二章课堂笔记
  • Maven基本使用(下)
  • Zenmap
  • Mysql Innodb存储引擎原理—链接如下
  • ARM base instruction -- csel
  • 小琳AI课堂:多模态模型的训练与应用
  • 人工智能安全治理框架导图
  • JavaScript-如何实现克隆(clone)函数
  • [ JavaScript ] 数据结构与算法 —— 链表
  • 【comparator, comparable】小总结
  • 3.7、@ResponseBody 和 @RestController
  • IP路由与转发
  • JWT究竟是什么呢?
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • Spark RDD学习: aggregate函数
  • SQLServer之创建显式事务
  • Vue2 SSR 的优化之旅
  • WebSocket使用
  • 从零开始在ubuntu上搭建node开发环境
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 翻译--Thinking in React
  • 区块链将重新定义世界
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 译自由幺半群
  • 用Visual Studio开发以太坊智能合约
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • 正则学习笔记
  • 《码出高效》学习笔记与书中错误记录
  • 浅谈sql中的in与not in,exists与not exists的区别
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • ​​​​​​​开发面试“八股文”:助力还是阻力?
  • ​十个常见的 Python 脚本 (详细介绍 + 代码举例)
  • # 利刃出鞘_Tomcat 核心原理解析(八)-- Tomcat 集群
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (16)Reactor的测试——响应式Spring的道法术器
  • (2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (六)c52学习之旅-独立按键
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (五)MySQL的备份及恢复