工厂方法模式、抽象工厂模式

什么是工厂模式

工厂模式在其父类提供一个创建对象的方法,让其子类去实现具体返回那个对象

UML图

工厂方法模式
在这里插入图片描述
抽象工厂模式
在这里插入图片描述

两者的对比

从上述的UML图中我们可以看出,工厂方法模式只定义了一种产品继承关系,而抽象工厂可以定义多种产品继承关系。可以很优美的完成工厂的扩建,而产品的扩建则不满足开闭原则。工厂方法模式可以很好的满足工厂和商品的扩建,但在工厂和商品很多的情况下,未免显得很庞杂。
以下内容来自此网站

工厂模式使用场景

  • 当你在编写代码的过程中, 如果无法预知对象确切类别及其依赖关系时, 可使用工厂方法。
    • 工厂方法将创建产品的代码与实际使用产品的代码分离, 从而能在不影响其他代码的情况下扩展产品创建部分代码。例如, 如果需要向应用中添加一种新产品, 你只需要开发新的创建者子类, 然后重写其工厂方法即可。
  • 如果你希望用户能扩展你软件库或框架的内部组件, 可使用工厂方法。
    • 继承可能是扩展软件库或框架默认行为的最简单方法。 但是当你使用子类 替代标准组件时, 框架如何辨识出该子类?
    • 解决方案是将各框架中构造组件的代码集中到单个工厂方法中, 并在继承该组件之外允许任何人对该方法进行重写。
    • 让我们看看具体是如何实现的。 假设你使用开源 UI 框架编写自己的应用。 你希望在应用中使用圆形按钮, 但是原框架仅支持矩形按钮。 你可以使用 圆形按钮Round­Button子类来继承标准的 按钮Button类。 但是, 你需要告诉 UI框架UIFramework类使用新的子类按钮代替默认按钮。
    • 为了实现这个功能, 你可以根据基础框架类开发子类 圆形按钮 UIUIWith­Round­Buttons , 并且重写其 create­Button创建按钮方法。 基类中的该方法返回 按钮对象, 而你开发的子类返回 圆形按钮对象。 现在, 你就可以使用 圆形按钮 UI类代替 UI框架类。 就是这么简单!
      在这里插入图片描述
  • 如果你希望复用现有对象来节省系统资源, 而不是每次都重新创建对象, 可使用工厂方法。
    • 在处理大型资源密集型对象 (比如数据库连接、 文件系统和网络资源) 时, 你会经常碰到这种资源需求。

    • 让我们思考复用现有对象的方法:

    • 首先, 你需要创建存储空间来存放所有已经创建的对象。
      当他人请求一个对象时, 程序将在对象池中搜索可用对象。
      … 然后将其返回给客户端代码。
      如果没有可用对象, 程序则创建一个新对象 (并将其添加到对象池中)。这些代码可不少! 而且它们必须位于同一处, 这样才能确保重复代码不会污染程序。

    • 可能最显而易见, 也是最方便的方式, 就是将这些代码放置在我们试图重用的对象类的构造函数中。 但是从定义上来讲, 构造函数始终返回的是新对象, 其无法返回现有实例。

    • 因此, 你需要有一个既能够创建新对象, 又可以重用现有对象的普通方法。 这听上去和工厂方法非常相像。

  • 如果代码需要与多个不同系列的相关产品交互, 但是由于无法提前获取相关信息, 或者出于对未来扩展性的考虑, 你不希望代码基于产品的具体类进行构建, 在这种情况下, 你可以使用抽象工厂。
    • 抽象工厂为你提供了一个接口, 可用于创建每个系列产品的对象。 只要代码通过该接口创建对象, 那么你就不会生成与应用程序已生成的产品类型不一致的产品。

与其他设计模式的关系

  • 在许多设计工作的初期都会使用工厂方法模式 (较为简单, 而且可以更方便地通过子类进行定制), 随后演化为使用抽象工厂模式、 原型模式或建造者模式 (更灵活但更加复杂)。
  • 建造者重点关注如何分步生成复杂对象。 抽象工厂专门用于生产一系列相关对象。 抽象工厂会马上返回产品, 建造者模式则允许你在获取产品前执行一些额外构造步骤。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值