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
View Code

 


工厂模式

  • 工厂模式是一个在软件开发中用来创建对象的设计模式。
  • 说白了,就是抽出一个标志性的参数,然后制作一个通用的函数去指定到实例化哪个类(有点像工厂加工)。
  • 作用是将创建对象的代码和使用对象的代码解耦
 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")
View Code

 


构造模式

  • 构造模式由构造者、指挥者、成员类组成
  • 使用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方法顺序执行
View Code

 

posted @ 2022-08-17 22:36  umbrella~  阅读(482)  评论(0编辑  收藏  举报