| |
| import threading |
| import time |
| |
| class Singleton(object): |
| def __new__(cls, *args, **kw): |
| if not hasattr(cls, '_instance'): |
| orig = super(Singleton, cls) |
| cls._instance = orig.__new__(cls, *args, **kw) |
| return cls._instance |
| |
| class Bus(Singleton): |
| lock = threading.RLock() |
| def sendData(self,data): |
| self.lock.acquire() |
| time.sleep(3) |
| print "Sending Signal Data...",data |
| self.lock.release() |
| |
| class VisitEntity(threading.Thread): |
| my_bus="" |
| name="" |
| def getName(self): |
| return self.name |
| def setName(self, name): |
| self.name=name |
| def run(self): |
| self.my_bus=Bus() |
| self.my_bus.sendData(self.name) |
| |
| if __name__=="__main__": |
| for i in range(3): |
| print "Entity %d begin to run..."%i |
| my_entity=VisitEntity() |
| my_entity.setName("Entity_"+str(i)) |
| my_entity.start() |
| 单例模式的优点: |
| 1、由于单例模式要求在全局内只有一个实例,因而可以节省比较多的内存空间; |
| 2、全局只有一个接入点,可以更好地进行数据同步控制,避免多重占用; |
| 3、单例可长驻内存,减少系统开销。 |
| 单例模式的应用举例: |
| 1、生成全局惟一的序列号; |
| 2、访问全局复用的惟一资源,如磁盘、总线等; |
| 3、单个对象占用的资源过多,如数据库等; |
| 4、系统全局统一管理,如Windows下的Task Manager; |
| 5、网站计数器。 |
| 6、数据库配置,数据库连接池 |
| 7、应用程序的日志应用 |
| 1、单例模式的扩展是比较困难的; |
| 2、赋于了单例以太多的职责,某种程度上违反单一职责原则(六大原则后面会讲到); |
| 3、单例模式是并发协作软件模块中需要最先完成的,因而其不利于测试; |
| 4、单例模式在某种情况下会导致“资源瓶颈”。 |
工厂模式的定义如下:定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。其通用类图如下。其产品类定义产品的公共属性和接口,工厂类定义产品实例化的“方式”。
| import random |
| |
| class PetShop(object): |
| 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", pet) |
| print("it says",pet.speak()) |
| print("it eats",self.pet_factory.get_food()) |
| |
| class Dog: |
| def speak(self): |
| return "Dog" |
| |
| def __str__(self): |
| return "this is Dog" |
| |
| class Cat: |
| def speak(self): |
| return "Cat" |
| |
| def __str__(self): |
| return "this is Cat" |
| |
| class CatFactory: |
| def get_pet(self): |
| return Cat() |
| |
| def get_food(self): |
| return "cat food" |
| |
| class DogFactory: |
| def get_pet(self): |
| return Dog() |
| |
| def get_food(self): |
| return "dog food" |
| |
| def get_factory(): |
| return random.choice([DogFactory,CatFactory]) |
| |
| if __name__ == '__main__': |
| shop = PetShop() |
| |
| shop.pet_factory = get_factory()() |
| shop.show_pet() |
| 工厂模式、抽象工厂模式的优点: |
| 1、工厂模式巨有非常好的封装性,代码结构清晰;在抽象工厂模式中,其结构还可以随着需要进行更深或者更浅的抽象层级调整,非常灵活; |
| 2、屏蔽产品类,使产品的被使用业务场景和产品的功能细节可以分而开发进行,是比较典型的解耦框架。 |
| 工厂模式、抽象工厂模式的使用场景: |
| 1、当系统实例要求比较灵活和可扩展时,可以考虑工厂模式或者抽象工厂模式实现。比如, |
| 在通信系统中,高层通信协议会很多样化,同时,上层协议依赖于下层协议,那么就可以对应建立对应层级的抽象工厂,根据不同的“产品需求”去生产定制的实例。 |
1、工厂模式相对于直接生成实例过程要复杂一些,所以,在小项目中,可以不使用工厂模式;
2、抽象工厂模式中,产品类的扩展比较麻烦。毕竟,每一个工厂对应每一类产品,产品扩展,就意味着相应的抽象工厂也要扩展。
建造者模式的定义如下:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式的作用,就是将“构建”和“表示”分离,以达到解耦的作用。在上面订单的构建过程中,如果将order直接通过参数定义好(其构建与表示没有分离),同时在多处进行订单生成,此时需要修改订单内容,则需要一处处去修改,业务风险也就提高了不少。
在建造者模式中,还可以加一个Director类,用以安排已有模块的构造步骤。对于在建造者中有比较严格的顺序要求时,该类会有比较大的用处。
| class orderDirector(): |
| order_builder="" |
| def __init__(self,order_builder): |
| self.order_builder=order_builder |
| def createOrder(self,burger,snack,beverage): |
| self.order_builder.addBurger(burger) |
| self.order_builder.addSnack(snack) |
| self.order_builder.addBeverage(beverage) |
| return self.order_builder.build() |
| 优点: |
| 1、封装性好,用户可以不知道对象的内部构造和细节,就可以直接建造对象; |
| 2、系统扩展容易; |
| 3、建造者模式易于使用,非常灵活。在构造性的场景中很容易实现“流水线”; |
| 4、便于控制细节。 |
| 使用场景: |
| 1、目标对象由组件构成的场景中,很适合建造者模式。例如,在一款赛车游戏中,车辆生成时,需要根据级别、环境等,选择轮胎、悬挂、骨架等部件,构造一辆“赛车”; |
| 2、在具体的场景中,对象内部接口需要根据不同的参数而调用顺序有所不同时,可以使用建造者模式。例如:一个植物养殖器系统,对于某些不同的植物,浇水、施加肥料的顺序要求可能会不同,因而可以在Director中维护一个类似于队列的结构,在实例化时作为参数代入到具体建造者中。 |
原型模式定义如下:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
需要注意一点的是,进行clone操作后,新对象的构造函数没有被二次执行,新对象的内容是从内存里直接拷贝的。
| from copy import copy, deepcopy |
| class simpleLayer: |
| background=[0,0,0,0] |
| content="blank" |
| def getContent(self): |
| return self.content |
| def getBackgroud(self): |
| return self.background |
| def paint(self,painting): |
| self.content=painting |
| def setParent(self,p): |
| self.background[3]=p |
| def fillBackground(self,back): |
| self.background=back |
| def clone(self): |
| return copy(self) |
| def deep_clone(self): |
| return deepcopy(self) |
| if __name__=="__main__": |
| dog_layer=simpleLayer() |
| dog_layer.paint("Dog") |
| dog_layer.fillBackground([0,0,255,0]) |
| print "Background:",dog_layer.getBackgroud() |
| print "Painting:",dog_layer.getContent() |
| another_dog_layer=dog_layer.clone() |
| print "Background:", another_dog_layer.getBackgroud() |
| print "Painting:", another_dog_layer.getContent() |