单例模式分析和思想

简介: singleton(单例)模式被熟知的原因是因为它限制了类的实例化次数只能一次,单例模式,在该实例不存在的勤快下,可以通过一个方法创建一个类来实现创建类的新实例;如果实例已经存在,则会简单返回该对象的引用。单例模式不同于静态类(或对象),因为我们可以推迟它们的初始化,这通常是因为它需要一些信息,而这些信息在初始化期间可能无法获取,对于没有察觉到之前的引用代码,它们不会提供方便检索方法,

singleton(单例)模式被熟知的原因是因为它限制了类的实例化次数只能一次,单例模式,在该实例不存在的勤快下,可以通过一个方法创建一个类来实现创建类的新实例;如果实例已经存在,则会简单返回该对象的引用。单例模式不同于静态类(或对象),因为我们可以推迟它们的初始化,这通常是因为它需要一些信息,而这些信息在初始化期间可能无法获取,对于没有察觉到之前的引用代码,它们不会提供方便检索方法,这是因为它既不是对象,也不是由一个single返回的类,而是一个结构,在js中,singleton充当共享资源命名空间,从全局命名空间中隔离出代码实现,从而函数提供单一访问点。

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> mySingleton = (<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span> {</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//实例保持了singleton的一个引用</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> instacnce;
    <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">init</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span> {</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//私有方法和变量</span>
        funciton privateMethod(){
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//...</span>
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> privateVariable = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"private"</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> privateRandomNumber = <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Math</span>.random();
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*这里定义单例代码*/</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> {
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//公有方法和变量</span>
            publicMethod: <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span> {</span>
                console.log(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'hello world'</span>);
            },
            publicProperty: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'test'</span>,
            getRandomNumber:<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>{</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> privateRandomNumber;
        }
        };
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//获取singleton的实例,如果存在就返回,不存在创建新的实例</span>
        getInstance: <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span> {</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!instance) {
                instance= init();
            }
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> instance;
        }
    };
})();

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*调用公有的方法来获取实例:*/</span>
mySingleton .getInstance().publicMethod();</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li></ul>

singleton模式适用性:

  1. 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时;
  2. 当唯一的实例应该是通过子类化可扩展的,并且客户应该无需要更改代码就能使用一个扩展的实例时。

    类的静态实例和singleton之间的区别:当singleton可以作为一个静态的实例实现时,它可以延迟构建,直到需要使用静态实例时,无需使用资源和内存。 
    如果我们有一个可以直接被初始化的静态对象,需要确保执行代码顺序总是相同,当我们有大量的源文件时,它并不能伸缩。

在实践中,当在系统中确实需要一个对象来协调其他对象时,singleton模式是很有用的。

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> SingletonTester = (<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span> {</span>

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//参数:传递给单例的一个参数集合</span>
    <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">Singleton</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(options)</span> {</span>

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置options变量为接收的参数或者为空(如果没有提供的话)</span>
        options= options|| {};
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置name参数</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.name = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'SingletonTester'</span>;
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置pointX的值</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.pointX = options.pointX || <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//从接收的参数里获取,或者设置为默认值</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置pointY的值</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.pointY = options.pointY || <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>;

    }

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//实例容器</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> instance;

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//静态变量和方法模拟</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> _static = {
        name: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'SingletonTester'</span>,

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//获取实例的方法</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//返回Singleton的实例</span>
        getInstance: <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(options)</span> {</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (instance === <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">undefined</span>) {
                instance = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Singleton(options);
            }
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> instance;
        }
    };
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> _static;
})();

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> singletonTest = SingletonTester.getInstance({ pointX: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span> });
console.log(singletonTest.pointX); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 输出 5 </span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li></ul>

singleton的存在往往表明系统中的模块要么是系统紧密耦合,要么是其逻辑过于分散在代码库中多个部分。由于一系列的问题:从隐藏的依赖到创建多个实例的难度、底层依赖的难度等等,singleton测试会更麻烦

目录
相关文章
|
人工智能 数据挖掘 SEO
【真实体会】花几百块买ChatGPT4.0账号一年值得吗?
GPT4.0大幅提升内容质量和数量,支持文本、图片、文件问答,内置专业工具如AI设计助手。每月20美元,高效应用于SEO、写作、数据分析等场景,能自动修正错误,增强互动性,还可生成高质量视频。虽然官网有限制,移动APP无此问题。对比GPT3.5,GPT4是性价比高的多面工具,适合内容创作者。查看详细教程,参见个人主页介绍。
1385 0
【真实体会】花几百块买ChatGPT4.0账号一年值得吗?
|
新零售 人工智能 Cloud Native
【年度重磅】阿里淘系全年技术总结黑皮书,1500页免费下载!
淘系技术将2020一整年的精华内容梳理合并,重磅推出【淘系技术2020技术年货】。在这本书中,你将看到:各技术栈下时新前沿的技术讲解与方法技巧、淘系技术大牛的职场成长经验&学习问答实录、年度精选技术人员必读书单、淘系经典开源项目介绍、2020淘系顶会 paper 全文。
47467 0
【年度重磅】阿里淘系全年技术总结黑皮书,1500页免费下载!
|
5月前
|
机器学习/深度学习 测试技术
ChronosX: 可使用外生变量的时间序列预测基础模型
时间序列预测中,基础模型虽在单变量任务中表现出色,但引入协变量支持仍面临挑战。Chronos研究团队提出ChronosX架构,通过适配器层有效整合历史与未来协变量信息,适用于任何单变量模型。实验表明,ChronosX显著提升预测性能,尤其在复杂数据集上优势明显。消融研究进一步验证了协变量模块的重要性。尽管需要轻量训练,但其灵活性和通用性为时间序列建模提供了新思路,未来或可通过类似LLM提示机制实现更高效的协变量处理。
232 16
ChronosX: 可使用外生变量的时间序列预测基础模型
|
5月前
|
人工智能 算法 安全
AI时代:不可替代的“人类+”职业技能
在生成式人工智能快速发展的背景下,关于“人类工作者是否会被算法取代”的焦虑日益增加。本文探讨了AI对职业的重塑作用,指出真正的挑战在于如何通过职业技能培训重新定义人类的不可替代性。文章分析了替代与创造的辩证关系,强调人机协作时代的核心能力,如架构设计力、情感智慧和伦理决策力,并提出职业技能培训应从岗位技能导向转向能力生态构建。最终,通过系统性培训发展“人类+”特质,使AI成为解放人类潜能的工具,而非竞争对手。
|
9月前
|
存储 人工智能 安全
阿里云服务器五代、六代、七代、八代实例简介及性能提升介绍参考
随着技术的不断进步,阿里云服务器实例也经历了多代升级,从五代实例到最新的八代实例,每一代都在性能、稳定性、能效比等方面取得了显著提升。有的用户由于是初次接触阿里云服务器,所以不是很清楚阿里云服务器五代、六代、七代、八代实例有哪些,它们各自在云服务器性能上有哪些提升。本文将详细介绍阿里云服务器五代、六代、七代、八代实例的特点及性能提升,以供了解及选择。
305 10
阿里云服务器五代、六代、七代、八代实例简介及性能提升介绍参考
|
8月前
|
存储 人工智能 搜索推荐
阿里云佘俊泉:边缘云场景的探索与机遇
阿里云佘俊泉:边缘云场景的探索与机遇
229 0
|
10月前
|
弹性计算 监控 测试技术
ecs e实例测评
阿里云 e实例性能稳定,适用于中小型 Web 应用。在 CPU 和内存性能测试中,e实例表现出色,尤其在资源密集型任务中具有较高的性价比。相比同配置的其他 ECS 规格,e实例在轻量化场景中更为均衡。价格方面,e实例低于传统 ECS 的 t5 实例,且在中国大陆市场具备一定优势。用户体验方面,控制台提供了清晰的实例创建流程和快速部署选项,但缺乏高级应用文档和性能优化指导。总体而言,e实例适合中小型企业和个人开发者使用。
185 5
|
Rust JavaScript 前端开发
Zig
Zig 是一门系统编程语言,旨在提供一种简单、安全且高效的方式来构建软件。它的设计受到了 Rust、C 和 C++ 的影响,但与这些语言相比,Zig 更加简单易用。Zig 的语法和抽象级别使得它易于学习和使用,同时它还提供了许多现代编程语言的功能,如高级类型、模块化编程和内存安全等。
578 6
|
Linux Apache 弹性计算
|
机器学习/深度学习 人工智能 编解码
《GAP8人工智能物联网芯片》:毫瓦级人脸识别 – 识别篇
人脸识别因在安全领域的不同应用(门锁,门禁,闸机等)而受到了学界,业界及媒体的广泛关注,同时人脸识别也可以被广泛应用于各种其他方案,如刷脸取纸,账户管理等等。设备可自动的使用者(区别于其他使用者)可以创造出完全不一样的用户体验,如人脸识别咖啡机可识别了解每个用户对不同咖啡的喜好程度,从而推荐或制作符合用户口味的咖啡。同时,咖啡供应商也可以根据结果进行更详细的市场分析,物流管控,生产调整等从而获得更高的利润。是否可以仅用数美金就让现有设备配备可以长期依赖电池运行的人脸识别功能? AliOS Things + GAP8让这一切可以轻松得以实现!
《GAP8人工智能物联网芯片》:毫瓦级人脸识别 – 识别篇