常用的设计模式
一、建造者
需求:
画人物,需要画一个人的左手,右手,左脚,右脚,身体,头部
画一个瘦子、画一个胖子
from abc import ABCMeta,abstractmethod
class Builder():
__metaclass__=ABCMeta
@abstractmethod
def draw_left_arm(self):
pass
@abstractmethod
def draw_right_arm(self):
pass
@abstractmethod
def draw_left_foot(self):
pass
@abstractmethod
def draw_right_foot(self):
pass
@abstractmethod
def draw_body(self):
pass
@abstractmethod
def draw_head(self):
pass
class Thin(Builder):
def draw_left_arm(self):
print("画左手")
def draw_right_arm(self):
print("画右手")
def draw_left_foot(self):
print("画左脚")
def draw_right_foot(self):
print("画右脚")
def draw_body(self):
print("画瘦身体")
def draw_head(self):
print("画头部")
class Fat(Builder):
def draw_left_arm(self):
print("画左手")
def draw_right_arm(self):
print("画右手")
def draw_left_foot(self):
print("画左脚")
def draw_right_foot(self):
print("画右脚")
def draw_body(self):
print("画胖身体")
def draw_head(self):
print("画头部")
class Director():
def __init__(self,person):
self.person=person
def draw(self):
self.person.draw_left_arm()
self.person.draw_right_arm()
self.person.draw_left_foot()
self.person.draw_right_foot()
self.person.draw_body()
self.person.draw_head()
if __name__=="__main__":
thin=Thin()
fat=Fat()
director_thin=Director(thin)
director_thin.draw()
director_fat=Director(fat)
director_fat.draw()
二、原型
对一个基类对象进行克隆复制,创造出与模型一样的副本去操作。
import copy
class Prototype:
def __init__(self):
self.__objects={}
def register_object(self,name,obj):
"""Register an object"""
self.__objects[name]=obj
def unregister_object(self,name):
"""Unregister an object"""
del self.__objects[name]
def clone(self,name,**attr):
"""Clone a registered object and update inner attributes dictionary"""
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):
#每一次实例化的时候,我们都只会返回着同一个instance对象
if not hasattr(cls,'_instance'):
cls._instance=super(Singleton,cls).__new__(cls)
return cls._instance
obj1=Singleton()
obj2=Singleton()
obj1.attr1="value1"
print(obj1.attr1,obj2.attr1)
print(obj1 is obj2)
四、适配器
将类的一个接口转换为客户希望的另一个接口
import os
class Dog(object):
def __init__(self):
self.name = "Dog"
def bark(self):
return "woof!"
class Cat(object):
def __init__(self):
self.name = "Cat"
def meow(self):
return "meow!"
class Human(object):
def __init__(self):
self.name = "Human"
def speak(self):
return "'hello'"
class Car(object):
def __init__(self):
self.name = "Car"
def make_noise(self, octane_level):
return "vroom%s" % ("!" * octane_level)
class Adapter(object):
"""
Adapts an object by replacing methods.
Usage:
dog = Dog
dog = Adapter(dog, dict(make_noise=dog.bark))
"""
def __init__(self, obj, adapted_methods):
"""We set the adapted methods in the object's dict"""
self.obj = obj
self.__dict__.update(adapted_methods)
def __getattr__(self, attr):
"""All non-adapted calls are passed to the object"""
return getattr(self.obj, attr)
def main():
objects = []
dog = Dog()
objects.append(Adapter(dog, dict(make_noise=dog.bark)))
cat = Cat()
objects.append(Adapter(cat, dict(make_noise=cat.meow)))
human = Human()
objects.append(Adapter(human, dict(make_noise=human.speak)))
car = Car()
car_noise = lambda: car.make_noise(3)
objects.append(Adapter(car, dict(make_noise=car_noise)))
for obj in objects:
print ("A", obj.name, "goes", obj.make_noise())
if __name__ == "__main__":
main()