设计并非完全随心所欲,而是由许多的因素在进行限制,表面上看似乎有无数种方案,但权衡各种方案的利弊之后,就只能选择其中很少的几条加入进项目。
起初惹起困惑的,是数据库操作的很多方法,都不是static的,而是默认的动态属性,受以往的影响,对这点有点疑惑。设计为静态,主要是基于节省资源考虑,静态方法和变量存储在程序的静态存储区,和全局存储区是在一个位置。静态变量并非属于任何一个对象,而是属于类本身,任何一个对象对静态变量的修改,都会在此静态存储区保存下去,也就是说,不论有多少个对象,他们在执行的时候,进行修改的,是同一片内存。将类的变量和方法设置为静态的,将只开辟一片内存,这块内存可以理解为所有的对象公用。如果只是一般的工具类,每一个对象不存储属于自己的值,不进行写操作,那么设置为静态的可以节省大量的空间。因为每个对象开辟属于自己的空间后,既然其中存储的内容都是一样的,那么将这块内存保存为类本身所有并无不妥,毕竟这些对象不会因为自己的值和写操作引发混乱。但是如果每个对象都需要保存属于自己的数据,而且每个对象之间对该数据的更改不能影响别的对象,那么就并不能将他们设为静态的,而应当每个对象单独的进行操作。
另外,思考这样的问题,如果数据库的操作类真的都设为静态方法,设想这样的情景,对象A要进行一项耗时10s的操作,在此期间,该静态存储区一直进行读写交替操作,对象B在此时请求一个耗时3s的紧急事务处理,那如果保证对象A不会因此受到影响?在这种情况加入互斥和死锁绝对是一种糟糕的决定,因为一旦此内存被加锁,那么在进行大并发量访问的时候,就会因为严重问题,单一时刻仅能由一个进程进行处理,会引发并行不可进行因素。
此外,在静态方法中,不能使用$this关键字,因为静态方法不能区分对象来执行。在静态方法中,只能使用静态变量,用self::来进行使用,就是因为这些变量存储的位置不属于任何的对象,导致这些数据无法被每个对象单独操作而不对其他对象进行干扰。
如果是多线程多进程的时候,每个用户需要保存自己的数据和连接,那就无法像一些工具一样进行静态处理。
在进行面向对象的设计时,必须严格遵循面向对象的五大设计原则,这些都不是空泛的理论,而是在设计中必须践行的规约。在阅读数据库操作类时,发现该类职责上并不清晰。
此数据库操作的设计,整体上来说还是很有条理的。
dbMysql类专门进行数据库的操作,例如:链接数据库,选择数据库,进行事务处理,日志记录,进行主从协调和负载均衡,以及执行sql语句。
dbResult类专门处理sql查询后的结果集,将结果集分成不同的类型返回,并实现迭代器的接口,以便将结果集进行遍历。
这种处理很符合单一职责原则,而且在调用的时候也很清晰,但是在dbMysql类中,存在三个方法,理应属于对结果集的处理,这三个方法是对dbMysql类的污染,致使dbMysql类的职责出现混淆。
出现这种情况的原因,极有可能是设计者为了贪图方便,直接在对数据库的处理类上加载了对结果集的处理,致使污染了以往的设计规范。
我需要深入研究面向对象的设计思想,以及关于数据库合理的设计模式,来杜绝这种情况的发生。