java设计模式-单例模式

问题分析:

首先来明确一个问题,那就是在某些情况下,有些对象,我们只需要一个就可以了,比如,一台计算机上可以连好几个打印机,但是这个计算机上的打印程序只能有一个,这里就可以通过单例模式来避免两个打印作业同时输出到打印机中,即在整个的打印过程中我只有一个打印程序的实例。
简单说来,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个(当然也可以不存在

单例模式的定义:

确保某一个类有且只有一个实例,而且自行实例化并向整个系统提供整个实例

单例模式的使用场景:

确保某个类有且只有一个对象的场景,避免产生多个对象那个消耗过多的资源,或者某种对象类型的对象只有应该有且只有一个。

实现单例模式的关键点:

1,构造函数不对外开放,一般为Private

2,通过一个静态方法或者枚举返回单例类对象

3,确保单例类的对象有且只有一个,尤其是在多线程环境下

单例模式有以下特点:

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

简单点呢就是:

首先,单例模式使类在程序生命周期的任何时刻都只有一个实例
然后,单例的构造函数是私有的,外部程序如果想要访问这个单例类的话
必须通过 GetInstance()来请求(注意是请求)得到这个单例类的实例。

懒汉模式:

public class Singleton  {
	   private Singleton(){};//私有构造函数:使外部不能使用构造函数来创建该对象
	   private static Singleton mSingleton=null;//私有静态常量没有实例化:private保证只能内部访问该变量,static与类有关
	   public static synchronized Singleton getSingleton(){//公有静态放法:加了一个同步
		   if(mSingleton=null)
		   {
		      mSingl eton=new Singleton();
		   }
		   return mSingleton;		
	}


何为懒汉式单例呢,可以这样理解,单例模式呢,其在整个应用程序的生命周期中只存在一个实例,懒汉式呢,就是这个单例类的这个唯一实例是在第一次使用 getSingleton()时实例化的,如果您不调用 getSingleton()的话,这个实例是不会存在的,即为 null。形象点说,就是你不去动它的话,它自己是不会实例化的,所以可以称之为懒汉

首先这个 Singleton 类会在在第一次调用 getSingleton()时创建一个实例,并将这个实例的引用封装在自身类中,然后以后调用 getSingleton()时就会判断这个 Singleton 是否存在一个实例了,如果存在,则不会再创建实例。而是调用以前生成的类的实例,这样下来,整个应用程序中便就只存在一个实例了。

优点:每次只在使用时被实例化,

缺点:每次调用getSingleton()都要进行同步,造成不必要的同步开销,不建议使用


饿汉模式:

public class Singleton  {
	   private Singleton(){};//私有构造函数:使外部不能使用构造函数来创建该对象
	   private static  final Singleton mSingleton=new Singleton();//私有静态常量并实例化:private保证只能内部访问该变量,static与类有关,final一旦初始化就不能修改
	   public static Singleton getSingleton(){//公有静态放法:只能通过此方法来获取静态常量
		   return mSingleton;		
	}

上面介绍了饿汉式单例,到这里来理解懒汉式单例的话,就容易多了,懒汉式单例由于人懒,所以其自己是不会主动实例化单例类的唯一实例的,而饿汉式的话,则刚好相反,其由于肚子饿了,所以到处找东西吃,人也变得主动了很多,所以根本就不需要别人来催他实例化单例类的为一实例,其自己就会主动实例化单例类的这个唯一类。


例子:一个公司只有一个CEO,可以有几个VP,无数个员工,但CEO只有一个

Staff.java

public class Staff{
  public void work(){
	  //干活
	}
}

VP.java

public class VP extends Staff {
	  @Override
	   public void work(){
		  //管理员工 
	   }
}

CEO.java

package com.hust.singleton;
//CEO 单例模式(饿汉模式)
public class CEO  extends Staff{
	   private CEO(){};//私有构造函数:使外部不能使用构造函数来创建该对象
	   private static  final CEO mCEO=new CEO();//私有静态常量并实例化:private保证只能内部访问该变量,static与类有关,final一旦初始化就不能修改
	   public static CEO getCEO(){//公有静态放法:只能通过此方法来获取静态常量
		   return mCEO;		
	}
	   	   @Override
	   public void work(){
		   //管理VP
	   }
	 
}
/*1.饿汉模式
 * public class Singleton  {
	   private Singleton(){};//私有构造函数:使外部不能使用构造函数来创建该对象
	   private static  final Singleton mSingleton=new Singleton();//私有静态常量并实例化:private保证只能内部访问该变量,static与类有关,final一旦初始化就不能修改
	   public static Singleton getSingleton(){//公有静态放法:只能通过此方法来获取静态常量
		   return mSingleton;		
	}
 * 2,懒汉模式,优点:每次只在使用时被实例化,缺点:每次调用getSingleton()都要进行听不,造成不必要的同步开销,不建议使用
 *  public class Singleton  {
	   private Singleton(){};//私有构造函数:使外部不能使用构造函数来创建该对象
	   private static Singleton mSingleton=null;//私有静态常量没有实例化:private保证只能内部访问该变量,static与类有关
	   public static synchronized Singleton getSingleton(){//公有静态放法:加了一个同步
		   if(mSingleton=null)
		   {
		      mSingl eton=new Singleton();
		   }
		   return mSingleton;		
	}
 * 
 * 
 * 
 */

Company.java

package com.hust.singleton;

import java.util.ArrayList;
import java.util.List;

public class Company {
     private List<Staff> mAllStaffs=new ArrayList<Staff>();
     public void addStaff(Staff mStaff) {
    	 mAllStaffs.add(mStaff);
	}
     public void showAllStaffs() {
		for(Staff mStaff:mAllStaffs){
			System.out.println("Obj:"+mStaff.toString());
		}
	}
}

Test.java

package com.hust.singleton;

import java.security.PublicKey;

public class TestSingleton {
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		  Company mCompany=new Company();
		  //CEO对象只能通过getCEO函数获取
		  Staff mCeo1=CEO.getCEO();
		  Staff mCeo2=CEO.getCEO();
		  mCompany.addStaff(mCeo1);
		  mCompany.addStaff(mCeo2);
		  //通过new创建VP对象		  
		  Staff mVP1=new VP();
		  Staff mVP2=new VP();
		  mCompany.addStaff(mVP1);
		  mCompany.addStaff(mVP2);
		  //通过new创建Staff对象
		  Staff mStaff1=new Staff();
		  Staff mStaff2=new Staff();
		  Staff mStaff3=new Staff();
		  mCompany.addStaff(mStaff1);
		  mCompany.addStaff(mStaff2);
		  mCompany.addStaff(mStaff3);
		  
		  mCompany.showAllStaffs();
		 
	}

}

输出结果:

Obj:com.hust.singleton.CEO@15db9742
Obj:com.hust.singleton.CEO@15db9742//只有一个实例
Obj:com.hust.singleton.VP@6d06d69c
Obj:com.hust.singleton.VP@7852e922
Obj:com.hust.singleton.Staff@4e25154f
Obj:com.hust.singleton.Staff@70dea4e
Obj:com.hust.singleton.Staff@5c647e05


你可能感兴趣的:(java设计模式-单例模式)