第二十篇 设计模式之单例模式
1、当所有实例中封装的数据相同的时候,才适用于单例模式
2、静态方法+静态字段
单例模式作用:节省内存,单例模式保证内存中存在一个实例
下面就是结合单例模式实现的web应用程序
1 from wsgiref.simple_server import make_server 2 class ConnectionPool: 3 __instance = None 4 def __init__(self): 5 self.ip = "1.1.1.1" 6 self.port = 3306 7 self.pwd = "123" 8 self.username = "xxxx" 9 #去连接 10 self.conn_list = [1,2,3,4,5,6,7,8,9,10] 11 @staticmethod 12 def get_instance(): 13 #这里判断是否有值,如果有就执行没有else 14 if ConnectionPool.__instance: 15 return ConnectionPool.__instance 16 else: 17 #创建一个对象,并将对象赋值给静态字段__instance 18 ConnectionPool.__instance = ConnectionPool() 19 return ConnectionPool.__instance 20 def get_connection(self): 21 # 获取连接 22 import random 23 r = random.randrange(1,11) 24 return r 25 def index(): 26 p = ConnectionPool.get_instance() 27 conn = p.get_connection() 28 return "IIII" + str(conn) 29 def new(): 30 return "nnn" 31 def RunServer(environ, start_response): 32 start_response('200 OK', [('Content-Type', 'text/html')]) 33 #接收用户的url 34 url = environ['PATH_INFO'] 35 if url.endswith("index"): 36 ret = index() 37 return ret 38 elif url.endswith("new"): 39 ret = new() 40 return ret 41 else: 42 return "404" 43 if __name__ == '__main__': 44 httpd = make_server('', 800, RunServer) 45 print "Serving HTTP on port 800..." 46 #这里有一个循环死循环,只要客户端请求就会执行Runserver函数 47 httpd.serve_forever()
分析核心:
class ConnectionPool: __instance = None def __init__(self): self.ip = "1.1.1.1" self.port = 3306 self.pwd = "123" self.username = "xxxx" #去连接 self.conn_list = [1,2,3,4,5,6,7,8,9,10] @staticmethod def get_instance(): #这里判断是否有值,如果有就执行没有else if ConnectionPool.__instance: return ConnectionPool.__instance else: #创建一个对象,并将对象赋值给静态字段__instance ConnectionPool.__instance = ConnectionPool() return ConnectionPool.__instance obj1 = ConnectionPool.get_instance() print(obj1) obj2 = ConnectionPool.get_instance() print(obj2)
流程:静态方法需要类去执行,去判断直接跳过if,执行else,ConnectionPool()就是执行init方法,而ConnectionPool()赋值的时候是一个对象,即ConnectionPool.__instance =obj,这个时候静态节点值发生变化。之后再次判断最后得到obj。这里无论再有多少个对象,对象封装的数据是相同的也就是单例模式
对于单例模式不能够再用obj = Foo(),而是特殊方法obj = ConnectionPool.get_instance()
执行得到的结果如下:
1 <__main__.ConnectionPool object at 0x000001255F77C860>
2 <__main__.ConnectionPool object at 0x000001255F77C860>
可见每个访问的对象在我内存中都是相同的,如果不用单例模式,在大并发的情况下服务器会直接宕机