0%

基于Python实现的设计模式

1.Singleton mode 单例模式

一个类最多创建一个实例

装饰器实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 装饰器实现
def singleton(class_):
instances = {}
def getInstance(*args, **kwargs):
if class_ not in instances:
instances[class_] = class_(*args, **kwargs)
return instances[class_]
return getInstance


@singleton
class MyClass(object):

pass

元类实现

1
2
3
4
5
6
7
8
9
10
11
12
# 元类实现
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]


class MyClass(metaclass=Singleton):

pass

2.The Factory Pattern 工厂模式

解决对象创建问题

工厂模式属于创建型模式, 它提供了一种创建对象的最佳方式.
在工厂模式中, 我们在创建对象时不会对客户端暴露创建逻辑, 并且时通过使用一个共同的接口来指向新创建的对象.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 根据品牌名生产不同的汽车

# bmw 生产线
class bmw:

def __str__(self):
return "我生产了一台BMW汽车"

# benz 生产线
class benz:

def __str__(self):
return "我生产了一台Benz汽车"

# 创建一个汽车工厂
class MachineFactory:

def build(self, brand):
if brand == "bmw":
machine = bmw()
print(machine)
elif brand == "benz":
machine = benz()
print(machine)


machineFactory = MachineFactory()

# 根据不同的品牌名生产不同的汽车
machineFactory.build("bmw")
machineFactory.build("benz")

3.The Builder Pattern 构造模式

控制复杂对象的构造

当对象需要多个部分组合起来一步步创建,并且创建和表示分离的时候。可以这么理解,你要买电脑,工厂模式直接返回一个你需要型号的电脑,但是构造模式允许你自定义电脑各种配置类型,组装完成后给你。这个过程你可以传入builder从而自定义创建的方式。

假如我们要生产一台Computer, 我们需要首先定义一个Computer类, 他表示了一个Computer由那些组件组成. 然后定义一个Builer, Builer用于组装Computer. 最后定义一个Enginner, 工程师告诉Builer用那些配件参数生产Computer, 然后得到一台根据具体参数生产的Computer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# 首先我们先定义一个 Computer 类
# 它表示一个 Computer 都由那些参数设备组成
class Computer:

def __init__(self, serialNumber):
self.serial = serialNumber
self.memory = None
self.ssd = None
self.gpu = None

def __str__(self):
info = """
Memory: {}GB
SSD : {}GB
Graphics Card: {}
""".format(
self.memory,
self.ssd,
self.gpu
)
info = "\n".join(list(filter(lambda x: x.strip(), info.split("\n"))))
return info


# 定义一个建造者, 用于构造一个 Computer
class ComputerBuilder:

def __init__(self):
self.computer = Computer("W540")

def setMemory(self, amount):
self.computer.memory = amount

def setSSD(self, amount):
self.computer.ssd = amount

def setGPU(self, amount):
self.computer.gpu = amount


# 定义一个工程师, 他告诉建造者该如何构造一个 Computer
class Engineer:

def __init__(self):
self.builder = None

def buildComputer(self, memory, ssd, gpu):
self.builder = ComputerBuilder()
self.builder.setMemory(memory)
self.builder.setSSD(ssd)
self.builder.setGPU(gpu)

@property
def computer(self):
return self.builder.computer


# 接下来我们创建一个 engineer 实例
enginner = Engineer()
# engineer 构造了一个 computer
enginner.buildComputer(
memory=32,
ssd=1024,
gpu="GeForce RTX 3090"
)
# 获得 computer
computer = enginner.computer
print(computer)

4.The Prototype Pattern 原型模式

解决对象拷贝的问题

可以使用Python内置的copy模块实现. 拷贝分为深拷贝和浅拷贝, 这里我觉得有点像C里面的指针. 浅拷贝相当于复制了对象的指针, 还是指向同一个对象, 而深拷贝则完全复制了一个新的对象.
深拷贝的优点是对象之间完全独立互不影响, 但是这个操作会比较消耗资源.
浅拷贝的优点是仅仅复制了指向对象的指针, 因为引用的都是同一个对象, 这个操作比深拷贝消耗的资源要少得多, 但是因为指向同一个对象, 所以当对象需要进行某些操作时候要慎重考虑.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import json
import copy


# 定义一本书
class Book:

def __init__(self, name, author, price, **kwargs):
self.name = name
self.author = author
self.price = price
self.__dict__.update(kwargs)

def __str__(self):
print(self.__dict__.keys())
attrNames = list(self.__dict__.keys())
attrs = dict()
for name in attrNames:
attrs.setdefault(name, getattr(self, name))
return json.dumps(attrs, indent=4)


class Prototype:

def __init__(self):
self.objects = {}

def register(self, identifier, obj):
self.objects[identifier] = obj

def unregister(self, identifiter):
del self.objects[identifiter]

def clone(self, identifier, **kwargs):
"""克隆一个对象, 即对象的深拷贝"""
obj = self.objects.get(identifier)
if not obj:
raise ValueError("Incorrect object identifier: {}".format(identifier))
newObj = copy.deepcopy(obj)
# 实现拷贝时自定义更新
newObj.__dict__.update(kwargs)
return newObj


if __name__ == '__main__':

b1 = Book(
name="Python程序设计",
author="闹闹",
price="99",
edition="1"
)

property = Prototype()
cid = "A123456789"
# 注册了一本新书
property.register(cid, b1)
# 克隆一个新对象
b2 = property.clone(cid, edition="2")

for i in (b1, b2):
print(i)
print("ID b1: {} b2: {}".format(id(b1), id(b2)))

5.The Adapter Pattern 适配器模式

解决接口不兼容问题

未完待续…