再看别人一个程序的时候,发现他封装的mysql操作类所有的方法都是static的,,而封装的redis类的方法却又都不是static的,请问下这样设计有什么特殊的意义或者有什么特殊的考虑吗?
回复内容: 再看别人一个程序的时候,发现他封装的mysql操作类所有的方法都是static的,,而封装的redis类的方法却又都不是static的,请问下这样设计有什么特殊的意义或者有什么特殊的考虑吗?
没办法评价,他的选择针对他的代码使用的场景也许是适合的,比如有限的数据库对象,且80%以上的请求都需要操作数据库,这样他可以在进程初始化的时候就启动数据库连接,而较少使用redis,而且又有多个redis对象,这样的话如果总是把所有的redis在初始化的时候构造明显就造成了浪费。所以他做了这种选择。
建议学会思考,也要学会学习。
1- 作者写代码时的思路别人只能猜测,不会全中;
2- 不要认为你写不出来,别人写出来,那人家写的就是绝对正确的、优秀的;
3- 先自己答题,再参考别人的答案,千万不要被别人的思想先入为主;
4- 越大的项目出现烂代码的几率就越高,要去其糟粕,因为不可能一个人完成所有开发,而且就算一个人开发也有巅峰和低谷,设计的思路很好,具体编程时由于各种原因无法达到预期是太平常的事情。
回到问题本身,从我个人的经验(以及很多框架)来看,static方法通常都属于工具方法,如db::factory, app::getmodel, date::format,而对于数据库操作和redis操作,它们明显不属于工具方法,所以不建议静态化。
而对于mysql类所有方法都是static的,从大方向来说其实是败笔。开发者不太可能在db::insert方法内部进行数据库连接状态检测,所以必然早就连接了数据库,一方面如果当前进程完全不需要数据库介入,这次连接就浪费了,另一方面,这明显延长了数据库连接时间,即如果是迟绑定,本次数据库连接可能只要持续0.05s,而由于预绑定,实际上本次数据库连接持续了0.1s,且其中的0.05s是空闲的,在等待php进程处理其他逻辑,这两方面都增加了数据库压力。
--补充--
如果真的在db::insert中包含了数据库连接状态检测,一方面增加了额外的逻辑,另一方面不适合多数据库的项目(如果想兼容多数据库,那么在调用insert的时候还要允许传入数据库连接参数,好麻烦)
个人看法,仅供参考。
首先,static的执行效率高,因为脚本运行时就加载到了内存中,而new的话还需要实例化的过程,接着mysql因为sql语句相比较redis的操作方法要复杂,对于mysql封装的方法可能比较复杂,而redis的操作语句比较简单,作者可能懒得进行复杂的封装。