问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

工厂方法模式与抽象工厂模式的深度对比

创作时间:
作者:
@小白创作中心

工厂方法模式与抽象工厂模式的深度对比

引用
CSDN
1.
https://blog.csdn.net/danci_bto/article/details/137197454

工厂方法模式与抽象工厂模式是两种常用的设计模式,它们在创建对象的方式上有所不同。本文将从定义、结构、适用场景等多个维度对这两种模式进行深度对比,帮助读者更好地理解它们的特点和应用场景。

一、定义

工厂方法模式

工厂方法模式定义一个用于创建对象的接口,将具体实例化对象的工作推迟到子类中完成。这种设计模式的主要目的是创建对象时不用依赖于具体的类,而是依赖于抽象,从而提高系统的灵活性和可扩展性。

抽象工厂模式

抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。这种模式通过抽象化对象的创建过程,实现高内聚低耦合的设计原则,增强系统的可扩展性和可维护性。

二、结构图

参与者

工厂方法模式

  • 产品(Product): 定义工厂方法所创建的对象的接口。所有被创建的对象都是某个具体产品的实例。
  • 具体产品(Concrete Product): 实现产品接口的具体类。工厂方法模式所创建的每个对象都是某个具体产品类的实例。
  • 创建者(Creator): 声明工厂方法,该方法返回一个产品类型的对象。创建者可能提供工厂方法的默认实现,它返回一个默认的具体产品对象。
  • 具体创建者(Concrete Creator): 重写工厂方法以返回一个具体产品实例。每个具体创建者通常与一个特定的具体产品一一对应。

抽象工厂模式

  • 抽象工厂(Abstract Factory): 它声明了一组用于创建一系列产品的方法,每个方法都对应一个产品等级。抽象工厂可以看作是一个工厂的工厂,或者是一系列工厂的抽象。
  • 具体工厂(Concrete Factory): 它实现了抽象工厂中声明的创建产品的方法,以生产具有共同主题的具体产品。
  • 抽象产品(Abstract Product): 它是定义产品的接口,描述了所有产品所共有的特性或方法。
  • 具体产品(Concrete Product): 它实现了抽象产品中定义的接口,提供了具体的产品实现。

适用场景

工厂方法模式适用于需要创建单一类型对象的场景,而抽象工厂模式适用于需要创建一系列相互关联或相互依赖的对象的场景。

三、易混场景

场景

假设我们正在开发一个游戏,游戏中有多种类型的角色,每种角色都有不同的武器和技能。我们需要设计一个系统来创建和管理这些角色、武器和技能。

工厂方法模式

如果我们选择使用工厂方法模式,我们可以定义一个抽象的角色工厂类,它声明了一个创建角色的工厂方法。然后,我们可以为每种具体的角色类型创建一个具体的角色工厂类,这些工厂类实现了抽象角色工厂类中声明的工厂方法,用于创建具体类型的角色对象。同样地,我们也可以为武器和技能定义类似的工厂类和方法。

在这种情况下,如果我们需要创建一个具有特定武器和技能的角色对象,我们可能需要分别调用角色工厂、武器工厂和技能工厂的方法。这可能会导致代码中的耦合度增加,因为客户端代码需要知道如何组合使用这些工厂方法来创建完整的角色对象。

抽象工厂模式

如果我们选择使用抽象工厂模式,我们可以定义一个抽象的工厂接口,该接口声明了一组创建角色、武器和技能对象的工厂方法。然后,我们可以为每种具体的角色类型创建一个具体的工厂类,这些工厂类实现了抽象工厂接口中声明的所有工厂方法,用于创建特定类型的角色、武器和技能对象。

在这种情况下,客户端代码只需要知道如何使用抽象工厂接口即可创建完整的角色对象,而无需关心具体工厂类的实现细节。这有助于降低代码中的耦合度,提高系统的灵活性和可扩展性。然而,当需要添加新的角色类型或新的产品族时,可能需要修改抽象工厂接口和现有的具体工厂类,这可能会带来一些维护成本。

易混淆之处

在这个场景中,工厂方法模式和抽象工厂模式的易混淆之处在于它们都涉及创建多种类型的对象。然而,工厂方法模式侧重于通过继承来实现对象的创建逻辑的封装和扩展,而抽象工厂模式则侧重于通过组合来实现一系列相互关联或相互依赖的产品的创建逻辑的封装和扩展。因此,在选择使用这两种模式时,需要根据具体的系统需求和设计目标来进行权衡和决策。

注:
在实际应用中,这两种模式并不是互斥的,而是可以相互结合使用的。例如,我们可以在抽象工厂模式中使用工厂方法来创建具体的产品对象,从而实现更灵活和可扩展的系统设计。

五、总结

工厂方法模式

  1. 封装性: 工厂模式通过专门的工厂类来创建其他类的实例,隐藏了对象创建的具体逻辑,客户端只需要知道产品的抽象接口和工厂类提供的创建方法。
  2. 解耦: 工厂模式减少了客户端与具体产品类之间的依赖,客户端通过工厂接口与工厂类交互,无需了解具体实现细节。
  3. 单一职责: 每个工厂类通常只负责创建一种或一类产品,符合单一职责原则。
  4. 扩展性: 当需要添加新产品时,只需增加相应的具体产品类和对应的工厂类,而无需修改客户端代码。

工厂模式最佳实践和使用场景

  1. 当需要创建的对象具有复杂的初始化逻辑或依赖于外部资源时,使用工厂模式可以封装这些复杂性。
  2. 当系统中存在多个类似的产品,且这些产品的创建逻辑可能会变化时,使用工厂模式可以提高系统的灵活性和可维护性。
  3. 当希望将对象的创建与使用分离,以便在不修改客户端代码的情况下更换产品实现时,使用工厂模式可以实现这一目标。

抽象工厂模式关键点

  1. 产品族: 抽象工厂模式强调一系列相互关联或相互依赖的产品对象(产品族)的创建,而不仅仅是单个产品的创建。
  2. 一致性: 客户端通过抽象工厂接口获取一系列产品对象,确保这些对象在逻辑上是一致的、相互兼容的。
  3. 封装性: 抽象工厂模式封装了具体产品族的创建逻辑,客户端只需要与抽象工厂接口交互。
  4. 扩展性: 当需要添加新的产品族时,只需增加相应的具体工厂类,而无需修改现有代码(遵循开闭原则)。

抽象工厂模式最佳实践和使用场景

  1. 当系统需要处理多个产品族,并且每个产品族包含多个相互关联的产品时,使用抽象工厂模式可以方便地创建和管理这些产品族。
  2. 当希望确保客户端使用的产品对象来自同一个产品族,以保持逻辑上的一致性时,使用抽象工厂模式可以实现这一目标。
  3. 当产品的创建逻辑可能会因为不同的平台、配置或环境而有所不同时,使用抽象工厂模式可以方便地切换不同的产品族实现。

根据项目需求选用正确的模式的建议

  1. 分析需求: 首先明确项目中需要创建的对象类型以及它们之间的关系。如果只需要创建单一类型的对象,且对象的创建逻辑相对简单,那么工厂模式可能是更好的选择。如果需要创建多个相互关联的对象(产品族),则考虑使用抽象工厂模式。
  2. 考虑扩展性: 评估未来可能的产品变化。如果预计会有新的产品类型或产品族加入,那么选择更具扩展性的模式(如抽象工厂模式)可能更为合适。
  3. 遵循设计原则: 尽量遵循面向对象设计原则,如单一职责原则、开闭原则等。这些原则可以帮助你做出更合理的模式选择。
  4. 代码简洁性: 在满足功能需求的前提下,尽量选择使代码更简洁、易于理解和维护的模式。过度设计可能会增加系统的复杂性和维护成本。

应用考量

  1. 系统的复杂度: 如果系统相对简单,产品种类较少且不太可能发生变化,那么简单工厂模式可能是更好的选择。如果系统复杂,存在多个产品族且产品族之间可能存在较大差异,那么抽象工厂模式可能更合适。
  2. 可扩展性需求: 如果预计未来需要频繁添加新产品或新产品族,那么抽象工厂模式可能更具扩展性。因为抽象工厂模式可以通过添加新的具体工厂类来引入新产品族,而无需修改现有代码。而简单工厂模式可能需要修改工厂类以适应新产品的创建。
  3. 设计原则: 尽量遵循面向对象设计原则,如单一职责原则、开闭原则等。这些原则可以帮助你做出更合理的模式选择。例如,如果希望遵循开闭原则,那么抽象工厂模式可能更合适,因为它允许在不修改现有代码的情况下扩展系统。
  4. 代码简洁性: 在满足功能需求的前提下,尽量选择使代码更简洁、易于理解和维护的模式。过度设计可能会增加系统的复杂性和维护成本。因此,在选择设计模式时,需要权衡其带来的好处和可能增加的复杂性。

❤️ 选择简单工厂模式还是抽象工厂模式应根据具体项目的需求、复杂度和可扩展性要求来决定。在实际应用中,可以先从简单工厂模式开始,随着项目的发展和需求的变化,再考虑是否升级到抽象工厂模式或其他更复杂的模式。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号