设计模式(一)——单例模式

目录

 

单例模式的定义:

单例模式的特点:

单例类的优缺点:

单例模式的写法(懒汉式、饿汉式)

 懒汉模式和饿汉模式的区别

 使用注意事项:

 适用场景: 

 应用场景举例:


单例模式的定义:

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

单例模式的特点:

             1、单例类只能有一个实例;

             2、单例类必须足迹创建自己的唯一实例;

             3、单例类必须给所有其他对象提供这一实例;

单例类的优缺点:

             优点:

             1、在单例模式中,活动的单例类只有一个实例,对于单例类的所有实例化得到的都是相同的一个实例,这样就可以保证所有的对象都访问的是同一个实例;

             2、单例模式具有一定的伸缩性(灵活性),单例模式自己控制实例化进程,类在改变实例化进程上具有相应的伸缩性(灵活性);

             3、节约系统资源,由于在系统内单例类只有唯一的实例,因此可以节约系统资源,当某一操作需要频繁创建和销毁对象时,单例模式无疑可以提高系统的性能;

             4、单例模式可以避免对资源的多重占用,例如一个写文件操作,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作;

             缺点:

             1、不适用于变化的对象,如果统一类型的对象总是要在不同的用例场景中发生变化,单例模式就容易引起数据的错误,无法保存彼此的状态;

             2、单例类扩展很困难,由于单例模式中没有抽象层,因此单例模式在扩展上有很大的困难;

             3、单例类的职责过重,在一定程度上违背了“单一职责原则”;

            4、滥用单例将出现的负面问题,如为节省资源将数据库连接池对象设计成单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间没有使用,可能会被当成垃圾回收,而导致中间状态的丢失;

单例模式的写法(懒汉式、饿汉式)

             懒汉式:

public class Singleton {
	private Singleton() {};//将构造方法设置为私有,避免类在外部被实例化
	private static Singleton single=null;
	public static Singleton getInstance() {//单例的唯一实例只能通过getInstance()方法访问,创建
		if(single==null) {
			single=new Singleton();
		}
		return single;
	}
}

  懒汉式单例是非线程安全的,在并发的环境下可能导致多个实例被创建,要保证懒汉式单例的线程安全有三种方法:

/*方法一:在getInstance()方法上加同步*/
	
	public static synchronized Singleton getInstance() {
		if(single==null) {
			single=new Singleton();
		}
		return single;
	}
//方法一每一次调用都需要同步,会影响程序的性能;



/*方法二:双重检查锁定*/
	
	public static Singleton getInstance() {
		if(single==null) {//第一次判断
			synchronized (Singleton.class) {
				if(single==null) {//第二次判断
					single=new Singleton();
				}
			}
		}
		return single;
	}
//只有第一次调用时会同步;


/*方法三:静态内部类创建实例*/
public class Singleton{
  private Singleton() {};
	 public static class Lazyholder{
		 private static final Singleton Instance=new Singleton();
	 }
	 public static Singleton getInstance() {
		return Lazyholder.Instance;
		}
}


       

   方法三较方法一和方法二好,因为方法三既实现了线程安全,又避免了同步带来的性能影响。

       饿汉式:类创建的时候同时创建一个静态的对象供系统使用,以后不再改变,因此饿汉模式是天生线程安全的;

public class Singleton1{
	private Singleton1() {};
	private static final Singleton1 single=new Singleton1();
	public static Singleton1 getInstance() {
		return single;
	}
}

 懒汉模式和饿汉模式的区别

  (1)实例的初始化:懒汉模式在调用类的getInstance 方法时才能初始化实例;

                                     饿汉模式在类一加载,就把单例初始化完成,在调用类的getInstance()方法时,实例已经存在了;

 (2)安全性:懒汉模式是非安全的;

                         饿汉模式是天生安全的;

 (3)资源加载和性能:懒汉模式会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次调用时要做初始化,

                                       因此存在一定的性能延迟;

                                       饿汉模式:创建类的时候同时实例化对象,其资源已经初始化完成,所以第一次调用时速度更快;

 

  使用注意事项:

                 1.使用时不能用反射模式创建单例,否则会实例化一个新的对象 ;

                 2.使用懒单例模式时注意线程安全问题 ;

           3.饿单例模式和懒单例模式构造方法都是私有的,因而是不能被继承的,有些单例模式可以被继承(如登记式模式)

  适用场景: 

单例模式只允许创建一个对象,因此节省内存,加快对象访问速度,因此对象需要被公用的场合适合使用,如多个模块使用同一个数据源连接对象等等。如:

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

     2.创建对象时耗时过多或者耗资源过多,但又经常用到的对象。 

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

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

    以下都是单例模式的经典使用场景: 
    1.资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。 
    2.控制资源的情况下,方便资源之间的互相通信。如线程池等。

 

应用场景举例:

网站的计数器:浏览网站的时候,常常会看到当前在线人数这样的一项内容。对于这样的一项功能,我们通常的做法是把当前的在线人数存放到一个内存、文件或者数据库中,每次用户登录的时候,就会马上从内存、文件或者数据库中取出,在其基础上加1后,作为当前的在线人数进行显示,然后再把它保存回内存、文件或者数据库里,这样后续登录的用户看到的就是更新后的当前在线人数;同样的道理,当用户退出后,当前在线人数进行减1的工作。所以,对于这样的一个需求,我们按照面向对象的设计思想,可以把它抽象为在线计数器这样一个对象。网站代码中凡是用到计数器的地方,只要new一个计数器对象,然后就可以获取、保存、增加或者减少在线人数的数量。不过,代码实际的使用效果并不好。假如有多个用户同时登录,那么在这个时刻,通过计数器取到的在线人数是相同的,于是他们使用各自的计数器加1后存入文件或者数据库。这样操作后续登陆的用户得到的在线人数,与实际的在线人数并不一致。所以,把这个计数器设计为一个全局对象,所有人都共用同一份数据,就可以避免类似的问题,这就是我们所说的单例模式的其中的一种应用。

单例模式能够保证一个类仅有唯一的实例,并提供一个全局访问点。

数据库连接池的设计一般采用单例模式,数据库连接是一种数据库资源。软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的。当然,使用数据库连接池还有很多其它的好处,可以屏蔽不同数据数据库之间的差异,实现系统对数据库的低度耦合,也可以被多个系统同时使用,具有高可复用性,还能方便对数据库连接的管理等等。数据库连接池属于重量级资源,一个应用中只需要保留一份即可,既节省了资源又方便管理。所以数据库连接池采用单例模式进行设计会是一个非常好的选择。

 

文件管理器。由于Windows操作系统是一个典型的多进程多线程系统,那么在创建或者删除某个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象。采用单例模式设计的文件管理器就可以完美的解决这个问题,所有的文件操作都必须通过唯一的实例进行,这样就不会产生混乱的现象。

Windows 任务管理器,垃圾回收站等都是单例设计模式。

                        

 

 

 

 

 

 

你可能感兴趣的:(设计模式,设计模式)