简单工厂模式(Simple Factory Pattern):是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类.

简单工厂模式结构

Product 产品声明接口,创建者及其子类生成的所有对象都通用

Concrete ProductA/B是产品接口的不同实现

Creator 创建者声明工厂方法,此方法返回的类型必须与产品接口匹配,可以将工厂方法声明为抽象方法,强制其子类必须实现自己的方法

ConcreteCreatorA/B 重写工厂方法,以便返回不同的产品

 from __future__ import annotations
from abc import ABC, abstractmethod class Creator(ABC):
"""
Creator类声明应该返回产品类的对象的工厂方法。创建者的子类通常提供此方法的实现。使用abstractmethod方式,强制子类必须实现factory_method
""" @abstractmethod
def factory_method(self):
"""
创建者可以提供factory方法的一些默认实现。
"""
pass def some_operation(self) -> str:
"""
不关心是谁创建的产品,写了自己的业务,子类可以重写
""" # 调用工厂方法,创建一个产品
product = self.factory_method() # 使用产品,不关心产品类型
result = f"创建者不关心产品类型, {product.operation()}" return result """
具体的创建者重写工厂方法以更改结果产品的类型。
""" class ConcreteCreator1(Creator):
"""
具体的生产者重写工厂方法以生产自己的产品。
具体产品实际上是从该方法返回的
""" def factory_method(self) -> ConcreteProduct1:
return ConcreteProduct1() class ConcreteCreator2(Creator):
def factory_method(self) -> ConcreteProduct2:
return ConcreteProduct2() class Product(ABC):
"""
产品接口声明所有具体产品必须实现的操作。abstractmethod强制子类实现其装饰的方法
""" @abstractmethod
def operation(self) -> str:
pass """
具体的产品提供了产品接口的各种实现。
""" class ConcreteProduct1(Product):
def operation(self) -> str:
return "{Result from ConcreteProduct1}" class ConcreteProduct2(Product):
def operation(self) -> str:
return "{Result from ConcreteProduct2}" def client_code(creator: Creator) -> None:
"""
客户端和具体生产者绑定,就可以获得不同的产品,不用关心具体的创建者是谁
""" print(f"client_code不在乎具体创建者\n"
f"{creator.some_operation()}", end="") if __name__ == "__main__":
print("ConcreteCreator1")
client_code(ConcreteCreator1())
print("\n") print("ConcreteCreator2")
client_code(ConcreteCreator2())

Product 产品声明接口,创建者及其子类生成的所有对象都通用

Concrete ProductA/B是产品接口的不同实现

Creator 创建者声明工厂方法,此方法返回的类型必须与产品接口匹配,可以将工厂方法声明为抽象方法,强制其子类必须实现自己的方法

ConcreteCreatorA/B 重写工厂方法,以便返回不同的产品

有哪些场景适合简单工厂模式呢?

在处理大型的资源密集型对象(例如数据库连接,文件系统和网络资源)时

事先不知道代码应使用的对象的确切类型和依赖关系时

要为库或框架的用户提供扩展其内部组件的方法时

想通过重用现有对象而不是每次都重建它们来节省系统资源时

优缺点:

优点:

可以避免创建者与具体产品之间的紧密耦合。

符合单一责任原则

符合开放/封闭原则,不破坏现有客户端代码,从而增加产品

缺点:

引入许多新的子类来实现该模式,因此代码可能变得更加复杂

作者:Andy
出处:http://www.cnblogs.com/onepiece-andy/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

最新文章

  1. dicom网络通讯入门(3)
  2. Centos网络配置
  3. hibernate对象关系实现(三)多对多实现
  4. FTP主/被动模式的原理
  5. ubuntu下搭建cocos2dx编程环境-中
  6. bnu 4352 XsugarX的疯狂按键识别(暴力模拟)
  7. 基于DDD的现代ASP.NET开发框架--ABP系列之2、ABP入门教程
  8. Python处理XML
  9. bootstrap-typeahead自动补充
  10. Ansible系列(三):YAML语法和playbook写法
  11. [编织消息框架][JAVA核心技术]动态代理应用12-总结
  12. Cannot retrieve metalink for repository: epel/x86_64. Please verify its path and try again
  13. php向mariaDB插入数据时乱码问题解决 --- mysqli_set_charset(设置默认字符编码)
  14. 1562. [NOI2009]变换序列【二分图】
  15. #C++初学记录(并查集)
  16. 用Python爬虫爬取广州大学教务系统的成绩(内网访问)
  17. CoderForces 518D Ilya and Escalator (期望DP)
  18. 基础篇:6.9)GD&T较线性尺寸公差的优缺点
  19. Qt快速入门学习笔记(画图篇)
  20. shell编程-数组

热门文章

  1. dedecms用runphp功能,写for循环,@me输出不出来
  2. SqlServer 查看数据库、添加数据文件
  3. C++矢量图形库系列(转)
  4. FPGA最小系统设计
  5. 海关单一窗口程序出现网络/MQ问题后自动修复处理
  6. Spring Boot实战之定制自己的starter
  7. maven的配置及基本操作
  8. Django 练习班级管理系统六 -- 编辑老师列表
  9. yum 安装apache php mysql
  10. jmeter压测学习9-响应断言