剑指offer-------单例模式

1.题目:

2.思路:

单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。

单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。要实现这一点,可以从客户端对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,“阻止”所有想要生成对象的访问。使用工厂方法来限制实例化过程。这个方法应该是静态方法(类方法),因为让类的实例去生成另一个唯一实例毫无意义。

对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态。因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。

要点:

         显然单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。

         从具体实现角度来说,就是以下三点:是单例模式的类只提供私有的构造函数,是类定义中含有一个该类的静态私有对象,是该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。

优点

一、实例控制

单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。

二、灵活性

因为类控制了实例化过程,所以类可以灵活更改实例化过程。

缺点

一、开销

虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。

二、可能的开发混淆

使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。

三、对象生存期

不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用。

3.代码:

(1)

public sealed class Singleton1
{
	//私有构造函数
	private Singleton1()
	{
	}
	
	//静态私有对象
	private static Singleton1 instance = NULL;
	
	//该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象
	public static Singleton1 Instance
	{
		get
		{
			if(instance == NULL)
				instance = new Singleton1();
				
			return instance;
		}
	}
}

(2)

public sealed class Singleton2
{
	private Singleton2()
	{
	}
	
	//上锁对象
	private static readonly object syncObj = new object();
	
	private static Singleton2 instance = NULL;
	
	public static Singleton2 Instance
	{
		get
		{
			lock(syncObj)    //同步上锁
			{
				if(instance == NULL)
					instance = new Singleton2();
			}
			return instance;
		}
	}
}

(3)

public sealed class Singleton3
{
	private Singleton3()
	{
	}
	
	//锁
	private static readonly object syncObj = new object();
	
	private static Singleton3 instance = NULL;
	
	public static Singleton3 Instance
	{
		get
		{
			if(instance == NULL)
			{
				lock(syncObj)
				{
					if(instance == NULL)
						instance = new Singleton3();
				}
			}
			
			return instance;
		}
	}
}

(4)

public sealed class Singleton4
{
	private Singleton4()
	{
	}
	
	private static Singleton4 instance = NULL;
	
	public static Singleton4 Instance
	{
		get
		{
			return instance;
		}
	}
}

(5)

public sealed class Singleton5
{
	private Singleton5()
	{
	}
	
	public static Singleton5 Instance
	{
		get
		{
			return Nested.instance;
		}
	}
	
	class Nested
	{
		static Nested()
		{
		}
		
		instance static readonly Singleton5 instance = new Singleton5();
	}
}
public class Singleton6 {
    /*
    *当第一次加载Singleton类时并不会初始化SINGLRTON,只有第一次调用getInstance方法的时候才会初始化SINGLETON
    *第一次调用getInstance 方法的时候虚拟机才会加载SingletonHoder类,这种方式不仅能够保证线程安全,也能够保证对象的唯一,
    *还延迟了单例的实例化,所有推荐使用这种方式
    * */
    private Singleton6() {
    }

    public Singleton6 getInstance() {
        return SingletonHolder.SINGLETON;
    }

    private static class SingletonHolder {
        private static final Singleton6 SINGLETON = new Singleton6();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_39503189/article/details/82959055