最近无意中看到一些对·单例模式·介绍的资料,有以下几个疑问:
- 很多资料说单例模式无法继承, 我自己觉得不对, 单例模式完全可以将private设置为protected, 然后将self设置为static来实现继承功能呀, 不知道说无法继承的是哪个角度思考的, 所以有疑问?
-
假设我的项目中有很多功能, 我的理解是 "用户每操作一下, 都会产生一个进程, 或者是一个进程中制作一次请求--相应操作, 然后当前操作在服务器运行完成并返回响应, 则进程结束, 这样的话, 假设你有个单例类是Log类, 用来记录日志, 那么本次进程结束后, 进程中的单例自然也就被销毁了, 另外一次操作的话, 这次操作会再次生成新的Log实例"
- 所以单例应该是按一个个的进程为单位来讨论的, 但是很多资料说 "如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。" 这怎么理解? 多长时间算是长?
- 毕竟我的项目根据功能点的不同, 可能有些功能点复杂, 有些简单, 我的Log实例要在每个功能中做日志记录, 难道还得考虑功能运行过长的话.... 我的日志会丢失一部分?
-
还有资料说:"滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出"
- 数据库连接池一般不就是个类似数组的容器么? 我第一次建立好数据库连接之后, 将连接对象放入连接池中, 如果进程中再次需要连接数据库的话, 直接从连接池中取出之前创建好的连接对象不就行了(而且我看比如TP3.2就是这么做的)
- 所谓 "连接池溢出" 是什么意思, 难道是说本次进程中有 n 个 不同的数据库连接, 导致连接池中存放数据对象过大导致的内存溢出?
- 不应该吧, 如果连接池是数组, 能放不少数据的啊, 而什么业务能在一个进程中操作这么多不同的数据库连接, 所以还是没能理解
- TP3.2框架使用单例也是非完全套用 三私一公 来实现的, 比如ThinkDriverDb 只做到静态化所有方法即可, 你即使new出来也没用, 这样是不是也没什么槽点?
1.单例即类只有一个示例,如果继承,那就会产生多个实例,此时已经不是单例了。
2.理解差不多没错,单例解决的是同一个请求内,多处使用同一个类的问题。。比如一个请求内,可能要查十次数据库,单例就是保证这十次使用的是同一个数据库连接实例,而不是每次查询都实例化一次。
3.滥用单例可能导致连接池溢出,这个问题应该只存在于 java 中或类似得,猜测:因为java采用数据库连接池技术,因为java是持久化服务,滥用单例导致连接得不到释放,内存不断上升导致溢出。而php这种请求结束,所有连接及内存都会释放,不存在这个问题。
4.所有的设计模式都是为了要实现功能而服务,所以需要先看你想实现什么东西。灵活运用各种模式,以及其变种,才能写出更好的代码。。。
所以不用执着于你的四个问题是否有答案,知道有单例这个东西,知道多个示例与单个示例的区别,然后你的代码需要优化的时候,按照自己的需求来就行