博主个人博客网站:文客
如果你想每天和我交流技术,可以关注一下我的个人博客网站:文客,我会每天在这里更新技术文章和面试题,也会及时收到大家的评论与留言,欢迎各位大佬来交流!
单例设计模式存在哪些问题?
在上一篇文章中,我们讲了单例设计模式的介绍和实现单例的方法。今天来说一说单例设计模式存在哪些问题。
大部分情况下,我们在项目中使用单例,都是用它来表示一些全局唯一类,比如配置信息类、连接池类、ID生成器类等。单例模式书写简洁、使用方便,在代码中,我们不需要创建对象,直接通过类似IdGenerator.getInstance().getId()这样的方法来调用就可以了。但是,这种使用方法有点类似硬编码(hard code),会带来诸多问题。接下来,我们就具体看看到底有哪些问题。
1.单例对OOP特性的支持不友好
我们知道OOP的四大特性是封装、抽象、继承和多态。单例这种设计模式对于其中的抽象、继承和多态的支持都不是很友好。我们还是通过IdGenerator来讲解。IdGenerator的使用方式违背了基于接口而非实现的设计原则,也就违背了OOP的抽象特性。如果未来,我们针对不同的业务采用不同的Id生成策略,比如用户id和物流id采用不同的id生成器来生成。为了应对这个需求,我们就需要修改所有用到过IdGenerator类的地方,这样代码的改动比较大。
除此之外,单例对继承和多态的支持也不友好。从理论上讲,单例类是可以被继承的,也可以实现多态,只不过实现起来会非常奇怪,导致代码的可读性变差。不明白设计意图的人,看到这样的设计,不免会感到莫名其妙。所以,往往当我们决定使用单例模式来设计时,就已经明确当前类未来不会有什么扩展,同时也做好了放弃继承和多态的准备。
2.单例会隐藏类之间的依赖关系
在我们阅读代码时,肯定希望一眼就能看出来类与类之间的依赖关系,搞清楚这个类使用的哪些外部类。
通过构造函数、参数传递等方式声明的类与类之间的关系,我们通过查看类或者函数的定义就能快速观察出来。但是单例类不需要显示的创建、不需要依赖参数传递,我们在函数中使用时,只需要得到实例然后调用方法就可以了。如