python设计模式
python设计模式有单例模式、工厂模式、建造者模式。
单例模式:
-
系统中只需要一个实例、或者必须只能一个实例时,就可以使用(必须使用)单例模式。
-
例1:当一个配置数据需要被频繁的多次的使用时,会有多个实例,会造成内存损耗。此时使用单例模式,就可以防止该情况。
-
使用的案例为python原生的模块(导入即实例),和共用配置类的使用。
-
例2:当一个文件可能同时被多个实例操作时,可能会出现报错(windows)或结果异常(linux),使用单例模式,可以避开该情况。
-
使用的案例为django/flask等自带的日志管理器。
-
单例模式下,即使改造
__new__
方法,也会出现多次调用__init__
方法。实际上实例化一个对象时,先
__new__
,再__init__
。因此改造了__new__
方法,__init__
还是无法避免被多次调用。可能会对结果有一定的影响因此建议使用一个装饰器来装饰,把
__new__
改造的方法写在自己的装饰器中

1 def Singleton(cls): 2 _ins = {} 3 4 def _sing(*args, **kwargs): 5 if cls not in _ins: 6 _ins[cls] = cls(*args, **kwargs) 7 return _ins[cls] 8 return _sing
工厂模式
- 工厂模式是一个在软件开发中用来创建对象的设计模式。
- 说白了,就是抽出一个标志性的参数,然后制作一个通用的函数去指定到实例化哪个类(有点像工厂加工)。
- 作用是将创建对象的代码和使用对象的代码解耦

1 class Person: 2 def __init__(self, name, gender): 3 self.name = name 4 self.gender = gender 5 6 class Male(Person): 7 def __init__(self, name, gender): 8 super().__init__(name, gender) 9 10 class Female(Person): 11 def __init__(self, name, gender): 12 super().__init__(name, gender) 13 14 class Factory: # 工厂模式 15 16 def get_person(self, name, gender): 17 18 # 抽出标志性的参数gender,通过判断gender,去指定初始化哪个类 19 # 这样就避免要调用多种接口。 20 # 但是,容易出现过度封装。 21 if gender == 'male': 22 return Male(name, gender) 23 else: 24 return Female(name, gender) 25 26 if __name__ == '__main__': 27 factory = Factory() 28 29 # 每次实例化对象时调用统一的接口即可 30 p1 = factory.get_person("太白", "male") 31 p2 = factory.get_person("小花", "female") 32 p3 = factory.get_person("玮哥", "male")
构造模式
- 构造模式由构造者、指挥者、成员类组成
- 使用abc模块,设置base类的方法为必须重写,通过这个方式防错
- 构造者作用是控制构造成员类的实例(防错)
- 指挥者作用是控制成员类实例的行为(统一指挥)

1 from abc import ABCMeta, abstractmethod 2 3 class Builder(metaclass=ABCMeta): 4 # 接口类,制定规范,只要此类必须要设置以下的被abstractmethod装饰的这些方法。 5 @abstractmethod 6 def draw_arm(self): 7 pass 8 9 @abstractmethod 10 def draw_foot(self): 11 pass 12 13 @abstractmethod 14 def draw_head(self): 15 pass 16 17 @abstractmethod 18 def draw_body(self): 19 pass 20 21 class Thin(Builder): 22 23 def draw_arm(self): 24 print("画手") 25 26 27 def draw_foot(self): 28 print("画脚") 29 30 def draw_head(self): 31 print("画头") 32 33 def draw_body(self): 34 print("画瘦身体") 35 36 37 class Fat(Builder): 38 39 def draw_arm(self): 40 print("画手") 41 42 def draw_foot(self): 43 print("画脚") 44 45 def draw_head(self): 46 print("画头") 47 48 def draw_body(self): 49 print("画胖身体") 50 51 class Director(): 52 def __init__(self, person): 53 self.person = person 54 55 def draw(self): 56 self.person.draw_arm() 57 self.person.draw_foot() 58 self.person.draw_head() 59 self.person.draw_body() 60 61 if __name__ == '__main__': 62 thin = Thin() 63 fat = Fat() 64 director_thin = Director(thin) # 组合 65 director_thin.draw() # 按照指挥者的类的draw方法顺序执行 66 director_fat = Director(fat) # 组合 67 director_fat.draw() # 按照指挥者的类的draw方法顺序执行
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了