创建型设计模式:提供实例化的方法,为适合的状况提供相应的对象创建方法
工厂方法
定义一个用户创建对象的接口,让子类决定实例化哪一个类,它使一个累类的实例化
延迟到其子类
- 当一个类不知道它所必须创建的对象的类的时候
- 当一个类希望由它的子类来指定它所创建的对象的时候
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化
class ChinaGetter:
def __init__(self):
self.trans = dict(dog=u"小狗", cat=u"小猫")
def get(self, msgid):
try:
return self.trans[msgid]
except KeyError:
return str(msgid)
class EnglishGetter:
def get(self, msgid):
return str(msgid)
def get_localizer(language="English"):
languages = dict(English=EnglishGetter, China=ChinaGetter)
return languages[language]()
e, g = get_localizer("English"), get_localizer("China")
for msgid in "dog parrot cat bear".split():
print(e.get(msgid), g.get(msgid))
抽象工厂
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
- 一个系统要独立于它的产品的创建、组合和表示时。
- 一个系统要由多个产品系列中的一个来配置时。
- 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
- 当你提供一个产品类库,而只想显示它们的接口而不是实现时
import random
class PetShop:
def __init__(self, animal_factory=None):
self.pet_factory = animal_factory
def show_pet(self):
pet = self.pet_factory.get_pet()
print("This is a lovely", str(pet))
print("It says", pet.speak())
print("It eats", self.pet_factory.get_food())
class Dog:
def speak(self):
return "woof"
def __str__(self):
return "Dog"
class Cat:
def speak(self):
return "meow"
def __str__(self):
return "Cat"
class DogFactory:
def get_pet(self):
return Dog()
def get_food(self):
return "dog food"
class CatFactory:
def get_pet(self):
return Cat()
def get_food(self):
return "cat food"
def get_factory():
return random.choice([DogFactory, CatFactory])()
if __name__ == "__main__":
shop = PetShop()
for i in range(3):
shop.pet_factory = get_factory()
shop.show_pet()
print("=" * 20)
建造者
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式
- 当构造过程必须允许被构造的对象有不同的表示时
class Director(object):
def __init__(self):
self.builder = None
def construct_building(self):
self.builder.new_building()
self.builder.build_floor()
self.builder.build_size()
def get_building(self):
return self.builder.building
class Builder(object):
def __init__(self):
self.building = None
def new_building(self):
self.building = Building()
class BuilderHouse(Builder):
def build_floor(self):
self.building.floor = 'One'
def build_size(self):
self.building.size = 'Big'
class BuilderFlat(Builder):
def build_floor(self):
self.building.floor = 'More than One'
def build_size(self):
self.building.size = 'Small'
class Building(object):
def __init__(self):
self.floor = None
self.size = None
def __repr__(self):
return 'Floor: %s | Size: %s' % (self.floor, self.size)
if __name__ == "__main__":
director = Director()
director.builder = BuilderHouse()
director.construct_building()
building = director.get_building()
print(building)
director.builder = BuilderFlat()
director.construct_building()
building = director.get_building()
print(building)
原型
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
- 当要实例化的类是在运行时刻指定时
- 动态装载
- 为了避免创建一个与产品类层次平行的工厂类层次时
- 当一个类的实例只能有几个不同状态组合中的一种时
import copy
class Prototype:
def __init__(self):
self._objects = {}
def register_object(self, name, obj):
self._objects[name] = obj
def unregister_object(self, name):
del self._objects[name]
def clone(self, name, **attr):
obj = copy.deepcopy(self._objects.get(name))
obj.__dict__.update(attr)
return obj
def main():
class A:
def __str__(self):
return "I am A"
a = A()
prototype = Prototype()
prototype.register_object('a', a)
b = prototype.clone('a', a=1, b=2, c=3)
print(a)
print(b.a, b.b, b.c)
if __name__ == '__main__':
main()
单例
保证一个类仅有一个实例,并提供一个访问它的全局访问点
- 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它
- 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例
class Singleton(object):
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
org = super(Singleton, cls)
cls._instance = org.__new__(cls, *args, **kw)
return cls._instance
if __name__ == '__main__':
class SingleSpam(Singleton):
def __init__(self, s):
self.s = s
def __str__(self):
return self.s
s1 = SingleSpam('spam')
print id(s1), s1
s2 = SingleSpam('spa')
print id(s2), s2
print id(s1), s1
评论区