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
|
class bmw:
def __str__(self): return "我生产了一台BMW汽车"
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
|
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
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
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
enginner = Engineer()
enginner.buildComputer( memory=32, ssd=1024, gpu="GeForce RTX 3090" )
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 适配器模式
解决接口不兼容问题
未完待续…