单例模式分析和思想

简介: 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测试会更麻烦

目录
相关文章
|
SQL 分布式计算 大数据
大数据Spark框架概述
大数据Spark框架概述
674 0
|
8月前
|
存储 资源调度 Cloud Native
VMware vCenter Server 8.0U3e 新增功能简介
VMware vCenter Server 8.0U3e 新增功能简介
290 4
VMware vCenter Server 8.0U3e 新增功能简介
|
5月前
|
监控 数据安全/隐私保护 Python
微信自动抢红包免费版,2025微信抢红包神器,微信红包挂苹果版【python仅供学习】
这个模拟项目包含5个模块:核心监控逻辑、用户界面、配置管理、实用工具和主程序入口
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
《探秘Hiplot:AI如何为上千图表模板实现精准分类推荐》
Hiplot是一款免费且功能强大的数据可视化AI,拥有上千种图表模板。它通过多维度数据理解、用户意图识别、机器学习模型和实时反馈优化等技术,实现精准的图表推荐。首先,AI对用户数据进行深度剖析,理解时间、产品、地域等维度特征;其次,利用自然语言处理识别用户需求;再者,基于大量历史数据训练的机器学习模型预测最适合的图表;最后,通过实时收集用户反馈不断优化推荐策略。这一系列AI技术的应用,使Hiplot能高效提供最合适的可视化方案,助力数据洞察与决策。
407 11
|
11月前
|
存储 消息中间件 前端开发
工厂人员定位管理系统架构设计:构建一个高效、可扩展的人员精确定位
本文将深入探讨工厂人员定位管理系统的架构设计,详细解析前端展示层、后端服务层、数据库设计、通信协议选择等关键环节,并探讨如何通过微服务架构实现系统的可扩展性和稳定性。
339 10
|
架构师 开发者
【悬念揭秘】DDD:那片隐藏在软件深处的业务乐土——.NET项目如何借力领域驱动设计,让复杂业务逻辑迎刃而解?
【8月更文挑战第28天】领域驱动设计(DDD)在.NET项目中的应用聚焦于将业务领域知识与软件开发紧密结合,通过构建清晰的领域模型管理复杂业务逻辑。DDD的核心概念包括限界上下文、聚合、实体等,确保模型与实现的统一。在.NET中,通过CQRS和事件源等模式提高系统响应性和可扩展性,实现业务事件驱动的解耦与协作。DDD不仅是一种设计方法,更是要求开发者深入理解业务的文化,助力.NET项目应对复杂挑战,实现业务与技术的融合。
239 6
|
存储 数据库连接 数据库
如何使用Python上传文件到FTP服务器
如何使用Python上传文件到FTP服务器
376 1
|
XML 前端开发 JavaScript
前端发展史
【4月更文挑战第17天】前端发展始于静态网页,经JavaScript与AJAX实现动态效果,步入Web 2.0时代,注重用户体验。响应式设计适应移动互联网,单页应用与Angular、React等框架提升开发效率。前端工程化、组件化及全栈角色成为趋势,持续创新以优化用户体验并应对技术与需求挑战。未来,前端开发者将继续引领互联网产品体验的革新。
238 1
|
达摩院 供应链 调度
【FlowShop流水线作业排班问题【数学规划的应用(含代码)】阿里达摩院MindOpt】
本文探讨了使用阿里巴巴达摩院的MindOpt工具解决FlowShop流水线作业排班的数学规划问题。FlowShop涉及到多台机器、多个工序和多个作业,目标是通过优化排班最小化总生产耗时。MindOpt通过数学规划方法,如线性或混合整数线性规划,将问题建模并转化为代码,利用云建模平台MindOpt Studio和MindOpt APL建模语言进行求解。案例中详细介绍了参数定义、变量解析、约束设置和目标函数,展示了如何通过MindOpt进行建模和求解,以达到最优化的生产调度。此外,文章还提供了代码示例和结果解析,帮助读者理解如何实际应用MindOpt解决这类问题。