Singleton(单例模式)

Singleton(单例模式)属于创建型模式,提供一种对象获取方式,保证在一定范围内是唯一的。

意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

其实单例模式在前端体会的不明显,原因有:

  1. 前端代码本身在单机运行,创建的任何变量都是天然分布式的,不需要担心影响另一个用户。
  2. 后端代码是一对多的,分辨出哪些资源是请求间共享的,哪些是请求内独有的很重要。

另外我们说到单例,是隐含了一个范围的,指的是在某个范围内单例,比如在一个上下文中,还是一个房间中,还是一个进程,一个线程中单例,不同场景范围会不同。

举例子

如果看不懂上面的意图介绍,没有关系,设计模式需要在日常工作里用起来,结合例子可以加深你的理解,下面我准备了三个例子,让你体会什么场景下会用到这种设计模式。

多人游戏的共享物品

玩过游戏的同学都知道,我们在每局游戏中使用的公共物品在当前房间中是唯一的,但在游戏房间间却不是唯一的,所以这些公共物品肯定有不同的类去描述,那每局游戏中怎么拿公共物品,可以保证拿到的是当前局内唯一的?

Redux 数据流

其实前端的 Redux 数据流本身就是单例模式,在一个应用中,数据是唯一的,但可以有不同的 UI 使用这份唯一的数据,甚至把一个表格组件展示在两个不同地方,比如全屏模式,但数据依然是一份,我们没有必要为了全屏展示表格,就让它再发一次取数请求,完全可以和原来的表格共享一份数据。

数据库连接池

每个 SQL 查询都依赖数据库连接池,如果每次查询都建立一次数据库连接池,则建立连接的速度会远远慢于 SQL 查询速度,因此你会怎么设计数据库连接池的获取方法?

意图解释

单例模式的意图很简单,几乎就是其字面含义:

意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

对于多人游戏的共享物品,比如一口锅,要保证在一局游戏内唯一,就要提供一种方法访问到唯一实例。

Redux 数据流的 connect 装饰器就是全局访问点的一种设计。

数据库连接池可以提前初始化好,并通过固定 API 提供这个唯一实例。

结构图

Singleton 是单例模式的接口,客户只能通过其定义的 instance() 访问实例,以保证单例。

代码例子

下面例子使用 typescript 编写。

class Ball {  private _instance = undefined

  // 构造函数申明为 private,就可以阻止 new Ball() 行为  private constructor() {}

  public static instance = () => {    if (this._instance === undefined) {      this._instance = new Ball()    }

    return this._instance  }}

// 使用const ball = Ball.getInstance()

可以仔细想想,为什么这个例子把单例写成了静态方法,而不是一个全局变量?其实全局变量也能解决问题,但由于会污染全局,要尽可能通过模块化方式解决,上面的例子就是一个较好的封装方式。

当然这只是一个最简单的例子,实际上单例模式还有几种模式:

饿汉式

初始化时就生成一份实例,这样调用时直接就能获取。

懒汉式

就是代码例子中写的,按需实例化,即调用的时候再实例化。

要注意,按需不一定是什么好事,如果 New 的成本很高还按需实例化,可能把系统异常的风险留到随机的触发时机,导致难以排查 BUG,另外也会影响第一次实例化时的系统耗时。

对 JAVA 来说,单例还需要考虑并发性,有 双重检测、静态内部类、枚举 等办法解决,这里不具体展开。

弊端

单例模式的问题有:

  • 对面向对象不太友好。对封装、继承、多态支持不够友好。
  • 不利于梳理类之间的依赖关系。毕竟单例是直接调用的,而不是在构造函数申明的,所以要梳理关系要看完每一行代码才能确定。
  • 可拓展性不好。万一要支持多例就比较难拓展,比如全局数据流可能因为微前端方案改成多实例、数据库连接池为了分治 SQL 改成多实例,都是有可能的,在系统设计之初就要考虑到未来是否还会保持单例。
  • 可测试性不好,因为单例是全局共享的,无法保证测试用例间的隔离。
  • 无法使用构造函数传参。

另外单例模式还可以被工厂方法所替代,所以不用特别纠结一种设计模式,可以结合使用,工厂函数也可以内嵌单例模式。

总结

单例模式概念、用法都简单,是架构设计常用方案,但要充分理解到单例模式的弊端,防止不恰当的使用。

讨论地址是:精读《设计模式 - Singleton 单例模式》· Issue #278 · dt-fe/weekly

如果你想参与讨论,请 点击这里,每周都有新的主题,周末或周一发布。前端精读 - 帮你筛选靠谱的内容。

关注 前端精读微信公众号

版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证)

socket可以写成单例嘛_精读设计模式 Singleton 单例模式相关推荐

  1. socket可以写成单例嘛_精读《设计模式 - Singleton 单例模式》

    Singleton(单例模式) Singleton(单例模式)属于创建型模式,提供一种对象获取方式,保证在一定范围内是唯一的. 意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 其实单例模 ...

  2. filter java 是单例的吗_JAVA 设计模式之 单例模式详解

    单例模式:(Singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点.单例模式是创建型模式.单例模式在现实生活中应用也非常广泛. 在 J2EE 标准中,S ...

  3. Spring 为啥默认把 bean 设计成单例的?

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:在滴滴和头条干了 2 年后端开发,太真实-个人原创100W+访问量博客:点击前往,查看更多 熟悉Spring开发 ...

  4. Spring 为啥默认把bean设计成单例的?这篇讲的明明白白的

    作者:小小木 juejin.im/post/5cab7ebf518825177637b2f9 熟悉Spring开发的朋友都知道Spring提供了5种scope分别是singleton.prototyp ...

  5. Spring为啥默认把bean设计成单例的

    熟悉Spring开发的朋友都知道Spring提供了5种scope分别是singleton.prototype.request.session.global session.而且默认情况下是single ...

  6. java servlet是单例吗_关于java:为什么apache servlet是单例?

    本问题已经有最佳答案,请猛点这里访问. HttpServletRequest request; HttpServletResponse response; public void doGet(Http ...

  7. java中单例设计模式登记式单例类_java23种设计模式-创建型模式之单例模式

    单例模式(Singleton) 单例对象(Singleton)是一种常用的设计模式.在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在.这样的模式有几个好处: 1.某些类创建比较频 ...

  8. java 单例 并发_完美的单例实现(The Perfect Singleton)

    原文链接  作者:Marek Piechut    译者:陈振阳 我经常遇到一些这样的Java程序员,他们不确定应该如何恰当的实现单例模式. 我不考虑在线程的环境中合适的实现.但是使用你能在网络上找到 ...

  9. python3的配置文件类单例实现_单例模式的几种实现方式及对比

    来源:博客园 作者:为何不是梦 链接:https://www.cnblogs.com/ibigboy/p/11423613.html 所谓单例就是在系统中只有一个该类的实例. 单例模式的核心分以下三个 ...

最新文章

  1. CodeSmith实用技巧(十五):使用快捷键
  2. 禁止显示“You have new mail in /var/spool/mail/root”
  3. 【JavaScript】【PPT】继承的本质
  4. 技巧:Silverlight应用程序中如何获取ASP.NET页面参数
  5. mysql时间日期操作
  6. Python条件判断和循环,range()函数
  7. python日历提醒_如何通过python发送日历邮件(ics)
  8. 自己编译redhat 9.0内核心得
  9. Nessus安全测试插件编写教程(2)
  10. Java Spring注解实现分析之@requestMapping工作原理
  11. 微信小程序开发之普通链接二维码
  12. tomcat增加处理线程数量
  13. 开始使用Power BI桌面
  14. Maven学习(三)-----Maven本地资源库
  15. [MySQL FAQ]系列 -- 如何利用触发器实现账户权限审计
  16. ES(Elasticsearch)解除索引只读限制
  17. cad统计多线段总长度插件_新手入门,学习CAD必须掌握,教你使用标注命令,绘图效率翻一倍...
  18. MySQL 数据库性能优化之缓存参数优化
  19. 135微信编辑html语言,135微信编辑器怎么在拉入的模板框框里添加文字
  20. 《大学生Python学习》社区正式运行,加入我们,每日学习,引燃青春~

热门文章

  1. javascript Blob数据解析 HUOBI火币api数据解析
  2. C#设计模式之6-适配器模式
  3. 阿里巴巴测试相关内容
  4. 为什么大多数程序员都抽烟_为什么大多数重新设计都会失败
  5. maven summer_我在Google Summer of Code的经历
  6. JavaScript类型强制解释
  7. tmux 上滚_实践中的tmux:回滚缓冲区
  8. word 职称计算机考试大纲,全国职称计算机考试Word2003大纲.doc
  9. 宏定义中有浮点数_GEO是什么?还可以定义新的数据类型吗?
  10. exists 实现查看表Activity中FmyId=1(具体数字在程序中动态给定)的好友发起的活动