首页 > 其他分享 >设计模式之单例模式

设计模式之单例模式

时间:2024-08-24 12:26:37浏览次数:9  
标签:GetInstance 模式 TaskManager 实例 static private 单例 设计模式

创建型模式将对象的创建和使用分离,在使用对象时无需关注对象的创建细节,从而降低系统的耦合度,让设计方案更易于修改和扩展。

模式名称 定义 学习难度 使用频率
单例模式 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例 一颗星 四颗星
简单工厂模式 定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类 两颗星 三颗星
工厂方法模式 定义一个用于创建对象的接口,让子类决定将哪一个类实例化 两颗星 五颗星
抽象工厂模式 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类 四颗星 五颗星
原型模式 使用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象 三颗星 三颗星
建造者模式 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 四颗星 两颗星

 

 

 

 

 

 

 

一、单例模式定义:确保某一个类只有一个实例,可以自行实例化并向整个系统提供这个实例,这个类成为单例类,它提供全局访问的方法。

二、实例:

 1 class TaskManager
 2 {
 3     private static TaskManager tm = null;
 4     
 5     private TaskManager(){...} //构造方法
 6     public void displayProcess(){...} //自定义方法
 7     public void displayServices(){...} //自定义方法
 8     
 9     public static TaskManager GetInstance()
10     {
11         if(tm == null)
12             tm = new TaskManager();
13         return tm;
14     }
15 }

1. 为了确保TaskManager实例的唯一性,需要禁止类的外部直接使用new来创建对象,因此需要将TaskManager的构造函数的可见性改为private。

2. 外部想要得到TaskManager类的实例,需要通过方法GetInstance(),获得TaskManager内部创建的实例tm。

3. 由于类外无法创建TaskManager对象,故需将GetInstance()定义为静态方法,方便类外可以直接通过类名访问。

4. 第一次调用GetInstance()方法时将创建唯一实例,再次调用时将返回第一次创建的实例。

三、饿汉式单例和懒汉式单例

1. 饿汉式单例:当类被加载时,静态变量tm会被初始化,此时类的私有构造函数会被调用,单例类的唯一实例将被创建。

 1 class TaskManager
 2 {
 3     private static TaskManager tm = new TaskManager();
 4     
 5     private TaskManager(){...}
 6     public void displayProcess(){...}
 7     public void displayServices(){...}
 8     
 9     public static TaskManager GetInstance()
10     {
11         return tm;
12     }
13 }

2. 懒汉式单例:即在第一次调用GetInstance方法时实例化,在类加载时并不自行实例化,这种技术又称为延迟加载(Lazy Load)技术,即需要的时候再加载实例。

为了避免多个线程同事调用GetInstance方法,可以使用锁。

class LazySingleton
{
        private static LazySingleton instance = null;
       
        private object SyncSelectObject = new object();

        private LazySingleton(){}  
       
        public static  LazySingleton GetInstance()
        {
                lock(SyncSelectObject )
                {
                    if (instance == null)
                    { 
                            instance = new LazySingleton ();
                    }
                    return instance;
               }                
        }
}    

 

上述代码虽然解决了线程安全问题,但是每次调用GetInstance时都需要进行线程锁定判断,将会导致系统性能大大降低。

饿汉式单例在类被加载时就将自己实例化,它的优点在于无序考虑多线程访问问题,可以确保实例的唯一性。

  • 从调用速度和反应时间角度来讲,由于单例对象一开始就得以创建,隐藏要优于懒汉式单例。
  • 但在类加载时该对象就需要创建,因此从资源利用效率角度来讲,饿汉式单例不及懒汉式单例,且系统加载时间可能会比较长。

懒汉式单例实现了延迟加载,但必须处理好多个线程同时访问的问题,这意味着出现多线程同时首次引用此类的概率变的较大,需要通过加锁进行控制,这将导致系统性能受到一定影响。

四、IoDH(Initialization on Demand Holder)技术

IoDH能够将两种单例的缺点都克服,而将两者的有点合二为一。

实现IoDH时,需在单例类中增加一个静态(static)内部类,在该内部类中创建单例对象,再将该单例对象通过getInstance方法返回给外部使用。

class Singleton
{
    private Singleton(){}  
    private static class HolderClass
    {
        private final static Singleton instance = new Singleton();
    }

    private static Singleton GetInstance()
    {
        return HolderClass.instance;
    }
   
    public static void main(String args[])
    {
        Singleton s1,s2;
        s1 = Singleton.GetInstance();
        s2 = Singleton.GetInstance();
        System.out.println(s1 == s2);//true
    }
}   

 由于静态单例对象没有作为Singleton的成员变量直接实例化,因此类加载时不会实例化Singleton。第一次调用GetInstance时将加载内部类HolderClass,在该内部类中定义了一个static类型的变量instance,此时会首先初始化这个成员变量。由于GetInstance()方法没有被任何线程锁定,因此其性能不会造成任何影响。

标签:GetInstance,模式,TaskManager,实例,static,private,单例,设计模式
From: https://www.cnblogs.com/LXLR/p/18218760

相关文章

  • 前端宝典十六:深入浅出8大设计模式
    本文主要探讨前端开发中的各种设计模式,主要分类有:单例模式建造者模式代理模式装饰器模式适配器模式策略模式观察者模式发布订阅模式通过对他们实际开发中的使用场景的解析,深入浅出的一起更全面直观的进行学习:一、单例模式介绍:单例模式确保一个类只有一个实例,并提供一个......
  • uefi模式无法读取u盘启动怎么办_uefi模式无法读取u盘启动解决方法
    最近有网友问我uefi模式下我按快捷方式或bios中都认别不了U盘,无法正常选择u盘启动进入pe安装系统,出现这种情况一般是bios中设置了uefi模式,而制作的u盘启动不支持uefi启动导致,那么uefi模式无法读取U盘启动怎么办?下面小编就教大家uefi模式无法读取u盘启动解决方法步骤。 u......
  • 设计模式(三)
    结构型模式装饰器模式:动态的给一个对象增加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。优/缺点:装饰模式是继承关系的一个替代方案。装饰模式可以动态地扩展一个实现类的功能。缺点:多层的装饰还是比较复杂何时使用:需要扩展一个类的功能,或给一个类增加附加功......
  • lua协程实现异步编程模式
    异步编程模式只是一个代码结构,c#中的async/await的写法就是异步编程模式,这边就是通过协程来达到和async/await类似的效果。 异步编程模式写法1:资源分帧加载这边运行环境用的是:Unity+xLua lua脚本:Assets/Lua/Test9.lua.txtlocal_Time=CS.UnityEngine.Timelocalfunct......
  • Linux下Redis的安装和部署(哨兵模式)
    1.哨兵模式配置文件redis服务 redis端口 哨兵端口 主从redis-1 7001 27001 主节点redis-2 7002 27002 从节点redis-3 7003 27003 从节点下载Rediscurl-Ohttp://download.redis.io/releases/redis-6.0.6.tar.gz解压Redistarxzvfredis-6.0.6.tar.gz进入redis-6.0.6目......
  • 设计模式概述和设计原则
    1.设计模式的概念软件设计模式(SoftwareDesignPattern),是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它描述了在软件设计过程中的一些不断重复发生的问题,以及该问题的解决方案。也就是说,它是解决特定问题的一系列套路,是前辈们的代码设计经验的总结,具......
  • 设计模式[4]-建造者模式
    代码:https://gitee.com/Aes_yt/design-pattern建造者模式建造者模式是将一个复杂对象,解构为多个简单的对象,然后一步一步慢慢构造成原对象。建造者模式主要包括四种角色:抽象建造者:具有产品的多个子部件的抽象接口,最终可以返回完整产品具体建造者:对抽象建造者的实现,有多个子......
  • 设计模式[3]-原型模式
    代码:https://gitee.com/Aes_yt/design-pattern原型模式概念原型模式将一个已经创建的实例作为原型,复制出一个和原型相同的新对象。包括三种角色:抽象原型:抽象角色,提供具体原型需要实现的接口具体原型:被复制的对象,实现抽象原型的接口客户端:发出创建对象的请求。例子:先......
  • 设计模式[2]-工厂模式
    代码:https://gitee.com/Aes_yt/design-pattern工厂模式1.简单工厂模式简单工厂模式主要包括三种角色:简单工厂:创建具体产品抽象产品:具体产品的父类具体产品:简单工厂创建的对象例子:设计一个游戏机类(GameConsole)作为抽象产品,然后设计具体的产品(PlanStation4,Xb......
  • 设计模式[1]-单例模式
    代码:https://gitee.com/Aes_yt/design-pattern单例模式单例模式(Singleton)是一种创建型设计模式,能够保证一个类只有一个实例,并提供了访问该实例的全局节点。单例的实现步骤有以下步骤,首先将默认构造函数设置为私有,然后创建一个静态方法来调用私有构造函数来创建对象。单例类......