首页 > 编程知识 正文

单例模式应用场景,单例模式的优缺点和使用场景

时间:2023-05-05 00:25:29 阅读:177530 作者:2029

单利模式的优缺点及使用场景

首先,我们将讨论单实例模式。

单实例模式(Singleton )也称为单实例模式,是一种常见的软件设计模式。 应用此模式时,必须确保单实例对象的类只存在一个实例。 大多数情况下,整个系统需要一个全局对象,这有助于协调整个系统的行为。 例如,在一个服务器程序中,服务器配置信息存储在文件中,用单实例对象集体读取这些配置数据,而服务过程中的其它对象从这个单实例对象获得这些配置信息这简化了复杂环境中的配置管理。

实现单实例模式的思路如下。

类返回用于获取对象的引用和实例的方法。 它必须是静态方法,通常使用名称getInstance。 调用此方法时,如果类保存的引用不为空,则返回此引用;如果类保存的引用为空,则创建类的实例,并将对该实例的引用赋予类保存的引用。 此外,还将类的构造函数定义为私有方法。 这样,其他代码就无法通过调用类的构造函数实例化类的对象,也无法从类提供的静态方法中获得类的唯一实例。

需要注意的地方:

在多线程APP应用中,必须小心使用单实例模式。 如果在尚未创建唯一实例时,两个线程同时调用创建方法,则它们不会同时检测到唯一实例的存在,因此会同时创建一个实例,创建两个实例,然后创建单个实例要解决此问题,请为指示是否实例化了类的变量提供互斥锁。 虽然这会降低效率。

优点:

1 .在单实例模式下,活动的单实例只有一个实例,并且单实例类的所有实例化都有相同的单个实例。 这样,[color=red]将阻止实例化其他对象,并允许所有对象访问单个实例[/color]

2 .单实例模式具有一定的伸缩性,类自身控制实例化过程在类改变实例化过程方面具有相应的伸缩性。

3 .提供对唯一实例的控制访问。

4 .因为系统内存中只存在一个对象,所以可以节约[color=red]系统资源[/color]。 如果[color=red]需要频繁创建和销毁的对象,单实例模式可以提高系统性能。 [/color]

5 .允许可变数量的实例。

6 .避免共享资源的多重占用。

坏处:

1 .不适用于变化的对象。 如果同一类型的对象总是尝试在不同的用例场景中变化,则单个用例会导致数据错误,并且无法保存彼此的状态。

2 .由于单利模型没有抽象层,对单例类的扩展存在很大困难。

3 .单例职责过重,在一定程度上违反了“单一职责原则”。

4 .滥用单实例可能会导致过多的程序共享连接池对象,如为节省资源而设计数据库连接池对象的单实例类。 如果实例化对象长时间不使用,系统将将其识别为垃圾并回收,对象将失去状态。

使用注意事项:

1 .不能在“反射”模式下创建单个实例。 否则,将实例化新对象

2 .使用懒惰的单实例模式时,注意线程安全问题

3 .饿单模式和懒单模式的建立方法均为私有,无法继承。 某些单例模式可以继承(

应用场景:

在单实例模式下,只能创建一个对象,从而节省内存并加快对象的访问速度。 因此,它适用于需要通用化对象的情况,例如,多个模块使用同一数据源连接到对象。 例如:

1 .需要频繁实例化并销毁的对象。

2 .对象创建时间过长或资源过多,但经常使用的对象。

3 .具有状态的工具类对象。

4 .频繁访问数据库和文件的对象。

以下都是单实例模式的典型使用场景。

1 .资源共享时,避免资源操作时的性能和损失等。 像上面的日志文件一样应用配置。

2 .控制资源时,便利资源之间的相互通信。 线程池等。

应用场景示例:

1 .外部资源:每台计算机都有多台打印机,但为了避免将两个打印作业同时输出到打印机,只有一个打印机后台打印程序。 内部资源:大多数软件都有一个或多个保存系统配置的属性文件。 这些系统需要管理这些属性文件的对象

2. Windows任务管理器(任务管理器)是典型的单实例模式。 )这个很熟悉吧。 想想看。 是吗? 要打开两个windows任务管理器吗? 不要相信,自己试试看哦~

3. windows的回收站也是典型的单实例APP。 在系统运行期间,回收站始终保持唯一的实例。

4 .网站计数器一般也是以单实例模式实现的。 不这样做的话就很难同步。

5.APP表示的日志APP一般以单实例模式实现,这是因为通常共享的日志文件保持打开状态。 因为只能操作一个实例,否则无法添加内容。

6 .加载web APP应用程序的配置对象通常也采用单实例模式,这是因为配置文件是共享资源。

7 .数据库连接池的设计也一般采用单实例模式。 因为数据库连接是数据库资源。 数据库系统使用数据库连接池,主要是节省开或关

关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。
    8. 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。
    9. 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。
    10. HttpApplication 也是单位例的典型应用。熟悉ASP.Net(IIS)的整个请求生命周期的人应该知道HttpApplication也是单例模式,所有的HttpModule都共享一个HttpApplication实例.
  
实现单利模式的原则和过程:
    1.单例模式:确保一个类只有一个实例,自行实例化并向系统提供这个实例
    2.单例模式分类:饿单例模式(类加载时实例化一个对象给自己的引用),懒单例模式(调用取得实例的方法如getInstance时才会实例化对象)(java中饿单例模式性能优于懒单例模式,c++中一般使用懒单例模式)
    3.单例模式要素:
        a.私有构造方法
        b.私有静态引用指向自己实例
        c.以自己实例为返回值的公有静态方法


1.饿汉式:单例实例在类装载时就构建,急切初始化。(预先加载法)
/*** 饿汉式(推荐)**/public class Test { private Test() { } public static Test instance = new Test(); public Test getInstance() { return instance; }}


优点
    1.线程安全
    2.在类加载的同时已经创建好一个静态对象,调用时反应速度快
缺点
    资源效率不高,可能getInstance()永远不会执行到,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化




2.bmdxs式:单例实例在第一次被使用时构建,延迟初始化。
class Test { private Test() { } public static Test instance = null; public static Test getInstance() { if (instance == null) { //多个线程判断instance都为null时,在执行new操作时多线程会出现重复情况 instance = new Singleton2(); } return instance; }}

优点:
    避免了饿汉式的那种在没有用到的情况下创建事例,资源利用率高,不执行getInstance()就不会被实例,可以执行该类的其他静态方法。
缺点:
    bmdxs式在单个线程中没有问题,但多个线程同事访问的时候就可能同事创建多个实例,而且这多个实例不是同一个对象,虽然后面创建的实例会覆盖先创建的实例,但是还是会存在拿到不同对象的情况。解决这个问题的办法就是加锁synchonized,第一次加载时不够快,多线程使用不必要的同步开销大。


3.双重检测
class Test { private Test() { } public static Test instance = null; public static Test getInstance() { if (instance == null) { synchronized (Test.class) { if (instance == null) { instance = new Test(); } } } return instance; }}

优点
    资源利用率高,不执行getInstance()就不被实例,可以执行该类其他静态方法
缺点
    第一次加载时反应不快,由于java内存模型一些原因偶尔失败




4.静态内部类
class Test { private Test() { } private static class SingletonHelp { static Test instance = new Test(); } public static Test getInstance() { return SingletonHelp.instance; }}

优点
    资源利用率高,不执行getInstance()不被实例,可以执行该类其他静态方法
缺点
    第一次加载时反应不够快


总结:
    一般采用饿汉式,若对资源十分在意可以采用静态内部类,不建议采用bmdxs式及双重检测




    转载请注明出处:点击打开链接http://blog.csdn.net/u010419467/article/details/48785589
    希望爱好编程的小伙伴能加这个群,互相帮助,共同学习。群号: 141877583

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。