背景 当你维护旧项目的时候,可能要优化一些原有的代码,又不想大改特改。毕竟设计模式的原则是对更改关闭,对扩展开放。假如大改特改势必会引入新的bug,增加测试的工作量。优化代码的目的是提高稳定性和效率,如果引入了新bug就得不偿失了。
这时我们可使用适配器或装饰器,在不改变调用的情况下,优化代码。
举个栗子 比如下面这代码段,封装了一个MySQL的连接,但是只返回了游标对象(cursor),没有返回连接对象(connnection) 。这样每次调用完这个函数之后,数据库连接不能关闭 ,很可能会导致连接量到达上限,引起性能问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 import MySQLdbdef mysql_connect (): conn = MySQLdb.connect(host='localhost' , port=3306 , user='root' , passwd='123456' , db='db' , charset='utf8' , use_unicode=False , unix_socket='/tmp/mysql3306.sock' ) cur = conn.cursor() return cur
使用适配器优化 所以我写了一个适配器类,通过适配器对象包装游标和连接 ,并且使mysql_connect函数返回适配器对象,以解决连接不能关闭的问题。 MySQLConnectAdapter适配器组合了cursor和connnection,**调用close方法的时候会同时关闭cursor和connnection。**重写__getattribute__方法,将除close之外的属性和方法重定向的self._cur对象上,实现对原有调用的兼容。需要注意,一旦重写__getattribute__方法,所以属性和方法查找都会通过自定义的__getattribute__,注意防止无穷递归。
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 import MySQLdbclass MySQLConnectAdapter (object ): def __init__ (self, conn, cur ): self ._conn = conn self ._cur = cur def __getattribute__ (self, name ): if name in ('close' , '_conn' , '_cur' ): return object .__getattribute__(self , name) else : return object .__getattribute__(self , '_cur' ).__getattribute__(name) def close (self ): self ._cur.close() self ._conn.close() def mysql_connect (): conn = MySQLdb.connect(host='localhost' , port=3306 , user='root' , passwd='123456' , db='db' , charset='utf8' , use_unicode=False , unix_socket='/tmp/mysql3306.sock' ) cur = conn.cursor() safe_cur = MySQLConnectAdapter(conn, cur) return safe_cur