zoukankan      html  css  js  c++  java
  • 设计模式1——单例模式

    单例模式(Singleton Pattern)的使用

    单例模式是最简单的设计模式之一

    这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

    一、单例模式优点

    单例模式主要是为了避免因为创建了多个实例造成资源的浪费,且多个实例由于多次调用容易导致结果出现错误,而使用单例模式能够保证整个应用中有且只有一个实例

    保证类在内存中只有一个对象,减少了内存开销;

    注意!!:

    1、单例类 只能有一个 实例。
    2、单例类必须自己创建自己的唯一实例。
    3、单例类必须给所有其他对象提供这一实例,且 用类名. 调用

    二、单例模式应用场景

    1. 资源管理器,资源对象数据的加载和卸载(无状态不需要实例化的对象);
    2. 生命周期在游戏中永不消毁的对象
    3. 单一客户端连接服务器等;

    三,单例模式的设计思想(复习时选看)

    (1)不允许其他程序用new对象。

    因为new就是开辟新的空间,在这里更改数据只是更改的所创建的对象的数据,如果可以new的话,每一次new都产生一个对象,这样肯定保证不了对象的唯一性。
    

    (2)在该类中创建对象
    因为不允许其他程序new对象,所以这里的对象需要在本类中new出来

    (3)对外提供一个可以让其他程序获取该对象的方法

    因为对象是在本类中创建的,所以需要提供一个方法让其它的类获取这个对象。

    四,单例模式的使用

    unity继承monobehavior的单例

    只需要在Awake()里面,添加一句instance = this;

    注意在Unity中不要使用new来创建MonoBehaviour实例

    public class  test : MonoBehaviour 
    {
      private static test instance;//1. static!!
      void Awake () 
      {	
               instance = this;
      }
        public static test GetInstance() 
        {
            
                return instance;
            
        }
    }
    

    使用方式

    test2.GetInstance().方法/属性/等  ;
    

    unity中范型写法(可不用双重锁)

    public class A<T> where T : new()//确保无参
    {
    	private static T instance;
    	
    	public static T GetInstance()
    	{
    
    		if (instance == null)
    		{
    			instance = new T();
    		}
    		return instance;
    	}
    }
    
    public class B : A<B>
    {
    }
    

    C#版本的 普通类单例。

    饿汉模式(常用)

     public class Singleton
        {
            // 自行预先实例化,内部定义自己唯一实例,只供内部使用 //
            private readonly static  Singleton Instance = new Singleton();
    
            private Singleton() 
            {
                // Do Something
            }
    
            // 提供外部访问的静态方法,来对内部唯一实例进行访问 //
            public static Singleton GetInstance()
            {
                return Instance;
            }
        }
    

    二 懒汉模式[线程不安全,不可用]

    public class Singleton {
    
       //1  private satic
       private static Singleton instance  = null;
        //2 提供私有构造函数;这样该类就不会被其他类实例化
       private Singleton(){}
    
       //3 获取唯一可用的对象
       public static Singleton GetInstance()
       {
         
              if (instance == null )
                    instance = new Singleton();
              return instance;//返回唯一实例,以便外部调用
          
       }
    
       
       
    }
    

    使用方式

    Singleton.GetInstance().方法/属性/等    ;
    
    • 两者比较:
    1. 所谓饿汉式,就是直接创建出类的实例化;

    ​ 而对于懒汉式,就是在需要的时候再创建类的实例化

    1. 饿汉式:简单来说就是空间换时间,因为上来就实例化一个对象,占用了内存,(也不管你用还是不用)(但是这个浪费可以忽略,所以这种方式也是推荐使用的)。

      懒汉式:简单的来说就是时间换空间,与饿汉式正好相反

    • 饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变

    以下解释引用https://blog.csdn.net/qq_37904799/article/details/81807954

    public static Singleton GetInstance()
    {
    		//判断singleton是否为null,如果为null,即判定需要实例化
    		if (singleton == null)
            {   //
    				
                singleton = new Singleton();
    		}
    		return singleton;
    }
    

    比如,现在有A线程和B线程,A线程刚好在这个GetInstance()方法中,刚刚判断完非空(此时为null),即需要创建实例,然而,就是这么巧,B线程抢到了CPU的执行权,A线程sleep了,这时,B线程也进行了这个判断,和A一样,都需要创建实例,而这时,A也抢到了CPU,这时,B就sleep了,然后A执行了实例化后,B又抢到CPU执行权,然后B也实例化,这时,出现问题了,A和B都实例化了一个对象,这就是赤果果的两个对象呀,单例呢,唯一呢,全都没了(这将导致第一个实例化的数据丢失)。

    三 双重校验锁模式的懒汉式【线程安全的】

    using System.Threading;//留意
    
    public class Singleton {
    	/**
    	 * 懒汉式变种,属于懒汉式中最好的写法,保证了:延迟加载和线程安全
    	 */
    	private static Singleton instance=null;
    	private Singleton() {};
    
    	public static Singleton GetInstance()
        {
    	 	if (instance == null) //进行了两次null检查
            {  
              synchronized (Singleton.class)
              { //synchronized之一,在方法定义时使用,多线程状态下,这个方法只能同时被同一个线程执行;
                  //可换用lock
                  if (instance == null)
                  {  
                	  instance = new Singleton();  
                  }  
              }  
          }  
          return instance;  
    }
    

    访问方式

    Singleton instance = Singleton.GetInstance();//获得引用
    

    四枚举[推荐使用,但无法继承]

    public enum SingletonEnum
     {
     	 instance; 
     
    	 private SingletonEnum() {}
     
     	public void method(){
     }
    

    }
    访问方式

    SingletonEnum.instance.method();
    

    五 泛型(结合双重锁)

    在一个案例中,我们可能需要使用到不止一个单例模式类,甚至更多。那么此时,使用泛型单例模式模板来实现单例模式,我们可以有两种不同的方法来实现它:

    4.3.1 首先我们来看下泛型模板,我们对泛型类进行约束,T只能是一个Class,并且有一个公共无参构造函数,代码如下:

    class Singleton<T> where T: class,new()  
    {  
        private static T instance;  
        private static readonly object syslock=new object();  
      
        public static T GetInstance()   
        {  
            if (instance == null)  
            {  
                lock (syslock) {  
                    if (instance == null)  
                    {  
                        instance = new T();  
                    }  
                }  
            }  
           return instance;  
        }  
    } 
    
    class B : Singleton<B> {  
        public void ss() {  
            Console.WriteLine("111");  
        }  
    }  
    

    萌新一枚,咳咳,不是食物链顶端的那种萌新,若有误,望指正

    参考:

    1. https://blog.csdn.net/dmk877/article/details/50311791
    2. https://blog.csdn.net/qq_37904799/article/details/81807954
    3. https://www.cnblogs.com/bananana/p/8566085.html
  • 相关阅读:
    jquery总结
    Reporting Services子报表
    Reporting Services分组及Toggle
    Reporting Services报表钻取
    Reporting Services环境
    两种很有用的组件
    Reporting Services正确显示页码
    Reporting Services发布
    Java面试题
    BigInteger引申的一个访问权限控制解决方案
  • 原文地址:https://www.cnblogs.com/laodada/p/12732285.html
Copyright © 2011-2022 走看看