一天学一个模式_第三天:单例模式

概念:
       顾名思义,就是只有一个实例。   
       作为对象的创建模式[GOF95], 单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。
要点:
   一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。
 在下面的对象图中,有一个"单例对象",而"客户甲"、"客户乙" 和"客户丙"是单例对象的三个客户对象。
 可以看到,所有的客户对象共享一个单例对象。而且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。
案例:
        先看两段代码(注意描述部分与注释);
 1,饿汉式单例类
   /**
     * @author wonter 
     * <b>描述:</b>饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变 <br>
     * <b>邮件:</b> yiyu1@163.com <br>
     */
  public class Singleton {
     //注意这是private 只供内部调用
     private static Singleton instance = new Singleton();
     private Singleton(){
     //空构造 防止被其他类new
     }
     //外部访问本class的静态方法,可以直接访问 
     public static Singleton getInstance() {
       return instance;  
      }
  }

 2,懒汉式单例类
    /**
     * @author wonter 
     * <b>比较:</b>  这个方法比上面有所改进,不用每次都进行生成对象,只是第一次。使用时生成实例,提高了效率! <br>
     *<b> 描述:</b>懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的 <br>
     * <b>邮件:</b> yiyu1@163.com <br>
     */
   public class Singleton {
     private static Singleton instance = null;
     //抽象集团类,线程互斥,排队模式
     public static synchronized Singleton getInstance() {     
     if (instance==null)// 线程1
       instance=new Singleton();
       //线程1后,才允许线程2运行
     return instance; 
     }
  }
 3,什么更适合于商业项目        
    /**
      * @author wonter 
      *<b> 描述:</b>直接 new 一个对象传递给类的成员变量 singletonpattern,你要的时候 getInstance()直接返回给你 <br>
      * <b>邮件:</b> yiyu1@163.com <br>
      */
   public class SingletonPattern {
      private static final SingletonPattern singletonPattern= new  SingletonPattern(); 
      //限制住不能直接产生一个实例
      private SingletonPattern(){
      //空构造 防止被其他类new
      }
             public synchronized static SingletonPattern getInstance(){ 
     return singletonPattern;
      }  
   }
     
   4.项目案例代码:(片段) 
  /**
   * <b>类描述:</b>集团代理类信息 <br>
   * <b>邮件:</b> yiyu1@163.com <br>
   * <b>手机:</b> 13018061144 <br>
   * <b>编写日期:</b> 2011-3-24 <br>
   * <b>最近修改日期:</b>2011-3-24 <br>
   * <b>最近修改日期:</b>2011-3-24 <br>
   * @see java.lang.String
   * @see java.lang.Integer
   * @author wonter
   * BlocDAO的代理类 BlocProxy <br>
   * 此类不允许用户new,因为多线程时不同操作会有死锁或者乐观锁的问题 (业务方法类)
   */
  public abstract class BlocProxy {
  public static final String FINDALL = "select * from Bloc where Blocstate=1";
  /**
   * <b>编写日期:</b> 2011-3-24 <br>
          * <b>最近修改日期:</b>2011-3-24 <br>
          * <b>最近修改日期:</b>2011-3-24 <br>
   * <b> 描述:</b>空构造 防止被其他类new<br>
   *  @see com.tb.crm.dao.factory.DAOAdapter#insert(java.lang.String,
   *      java.lang.Object[])
   * @author wonter
   */
  private BlocProxy() {

  }
  /**
   * <b>编写日期:</b> 2011-3-24 <br>
          * <b>最近修改日期:</b>2011-3-24 <br>
          * <b>最近修改日期:</b>2011-3-24 <br>
   * <b> 描述:</b> 抽象集团类,线程互斥,排队模式<br>
   * @see com.tb.crm.dao.factory.DAOAdapter#insert(java.lang.String,
   *        java.lang.Object[])    
   * @author wonter
   */
  public synchronized static BlocProxy getInstance() {
   return new BlocProxy() {
   };
  }
  /**
   * <b>编写日期:</b> 2011-3-24 <br>
          * <b>最近修改日期:</b>2011-3-24 <br>
   * <b>最近修改日期:</b>2011-3-24 <br>
   * 业务方法 :查询Bloc表全部信息 findAll
   * @see com.tb.crm.dao.factory.DAOAdapter#insert(java.lang.String,
   *      java.lang.Object[])     
   * @return List
   * @author wonter
   */
  public List findAll(){
   List list=null;
  
    try {
     if(list==null)// 线程1
     list = DAOFactory.getInstance(BlocDAO.class).findAll(
       FINDALL, Bloc.class);// 如果线程2,线程1后允许。
     return list;
    } catch (Exception e){
     e.printStackTrace();
    }
   return null;
  } 
好处:
 单例模式属于构建模式之一,实例控制--伸缩性
缺点:
 系统开销---开发混淆---对象生命周期
 /**
    * @author wonter 
    * <b>描述:</b> 一天学一个模式 更新中,请关注我的微博! <br>

    * <b>微博:</b>http://weibo.com/wontter<br>
    * <b>邮件:</b> yiyu1@163.com <br>
    */

原文地址:https://www.cnblogs.com/Javame/p/2156404.html