小菜学设计模式——单例模式

背景

保证只有一个实例时,你是否会想到单例模式

1、使用意图

保证只有一个实例,比如帮助窗体,没必要维护多个实例

2、生活实例

地球只有一个(不知道算不算单例的体现)

3、Java 例子(框架、JDK 、JEE)

单例模式的例子数不胜数,很常见的例子就是Spring的Controller是一个单例,但是如果按照单例模式编码规则来说,Servlet不是单例,但是他确实单实例,意思是Web容器只维护一个Servlet对象,其实也可以等同为单例的结果。另外,也不要一看到类名.getInstance()就以为那是单例模式,比如 Calendar.getInstance() 他不是单例模式,得到的对象都是不同是的实例。

  /**
     * Gets a calendar using the default time zone and locale. The
     * <code>Calendar</code> returned is based on the current time
     * in the default time zone with the default locale.
     *
     * @return a Calendar.
     */
    public static Calendar getInstance()
    {
        Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault());
         cal.sharedZone = true;
         return cal;
    }

4、模式类图

5、模式优点

单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。

通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。

因为Singleton类封装它的唯一实例,这样它可以严格地控制客户怎样访问它以及何时访问它。简单的说就是对唯一实例的受控访问。

单例模式编写最关键的一点是保证方法私有,同时获取实例时保证只有一个对象实例。

6、与类似模式比较

单例模式中主要需要解决的是两个问题:全局访问和实例化控制问题。

静态初始化方式是在自己被加载时就将自己实例化,被形象的称为饿汉式单例类。这种方式是类一加载就实例化的对象,要提前占用系统资源。

原先的单例模式处理方式第要在第一次被引用时,才会将自己实例化,所以称为懒汉式单例类。该方式面临着多线程访问的安全性问题,需要双重锁定这样的处理才能达到保证安全。

谈到单例,我觉得他和静态类还是要说说的,比如数学类这个静态类,静态类一加载,所有方法都会被加载到内存中,他是一种无状态的类,也就是没有实例拥有自己独有的属性,这种类一般就是工具类;然而,单例则不同,他自己内部保存了一份实例,这个实例就是维持了自身的状态,所以这是不同的;另外,因为静态所有的方法都为静态,所以,不能继承,但是单例不一样,单例的方法同样都不是静态的,他是可以继承的。二者共同点是构造方法都私有化。

7、代码实现

1)普通单例(一般单例只要保证构造方法私有),这种单例不安全,原因是多线程访问可能导致产生不止一个实例

/**

 * Singleton model (懒汉式单例)
 *@author:Heweipo
 *@version 1.00
 *
 */
public class Singleton {

 private static Object lock = new Object();

 private static Singleton instance;

 private Singleton(){
  // do nothing
 }

 public static Singleton getInstance(){
  // 其实可以在方法最外层枷锁,但是那样的话势必会影响性能,因为为空的情况只有一次出现
  if(instance == null){
   // 枷锁lock,在这之前是可能有多个方法还未初始化单例时进入的,所以后面还有判断一次
   synchronized(lock){
    // 如果引用为空,那么实例化单例,这里为什么还要判断呢?目的是防止多个方法同时进入
    if(instance == null){
     //单例首次实例化
     instance = new Singleton();
    }
   }
  }
  return instance;
 }
}

2)多线程单例,Double-Check Locking 双重锁定(在第一次被引用时,才会将自己实例化,所以也称之为 懒汉单例)

/**

 * Singleton model (懒汉式单例)
 *@author:Heweipo
 *@version 1.00
 *
 */
public class Singleton {

 private static Object lock = new Object();

 private static Singleton instance;

 private Singleton(){
  // do nothing
 }

 public static Singleton getInstance(){
  // 其实可以在方法最外层枷锁,但是那样的话势必会影响性能,因为为空的情况只有一次出现
  if(instance == null){
   // 枷锁lock,在这之前是可能有多个方法还未初始化单例时进入的,所以后面还有判断一次
   synchronized(lock){
    // 如果引用为空,那么实例化单例,这里为什么还要判断呢?目的是防止多个方法同时进入
    if(instance == null){
     //单例首次实例化
     instance = new Singleton();
    }
   }
  }
  return instance;
 }
}

3)静态初始化(在自己被加载时就将自己实例化,被称为饿汉式单例类,提前占用系统资源,不过更加建议使用这种,简洁)

/**
 * Singleton model (饿汗式单例)
 *@author:Heweipo
 *@version 1.00
 *
 */
public class Singleton {

 // 类加载时就实例化对象
 private static Singleton instance = new Singleton();

 private Singleton(){
  // do nothing
 }

 public static Singleton getInstance(){
  // 直接返回单例
  return instance;
 }
}
时间: 2024-08-01 20:03:34

小菜学设计模式——单例模式的相关文章

小菜学设计模式——单一职责原则

背景 本文标题为什么叫小菜学习设计模式,原因是本文内容主要是学习<大话设计模式>时的笔记摘要部分,当然,并不是记录书中小菜的学习过程,这个完全没有意义,而是指本人学习设计模式的成长之旅. 真诚的希望自己能够从一名小菜成长为一名大鸟! 编写的程序应该满足: 1)可维护 2)可扩展 3)可复用 4)够灵活 废话少说,言归正传,设计模式原则之:单一职责 书面理解 单一职责:就一个类而言,应该仅有一个引起它变化的原因 如果一个类承担职责过多,接等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制

小菜学设计模式——合成复用原则

背景 本文标题为什么叫小菜学习设计模式,原因是本文内容主要是学习<大话设计模式>时的笔记摘要部分,当然,并不是记录书中小菜的学习过程,这个完全没有意义,而是指本人学习设计模式的成长之旅. 真诚的希望自己能够从一名小菜成长为一名大鸟! 编写的程序应该满足: 1)可维护 2)可扩展 3)可复用 4)够灵活 废话少说,言归正传,设计模式原则之:合成复用原则 书面理解 合成复用原则:要尽量使用合成/聚合,尽量不要使用继承. 对象的继承关系是在编译时就定义好了,所以无法在运行时改变从父类继承的实现.子类

小菜学设计模式——接口隔离原则

背景 本文标题为什么叫小菜学习设计模式,原因是本文内容主要是学习<大话设计模式>时的笔记摘要部分,当然,并不是记录书中小菜的学习过程,这个完全没有意义,而是指本人学习设计模式的成长之旅. 真诚的希望自己能够从一名小菜成长为一名大鸟! 编写的程序应该满足: 1)可维护 2)可扩展 3)可复用 4)够灵活 废话少说,言归正传,设计模式原则之:接口隔离原则 书面理解 接口隔离原则:使用多个小的专门的接口,而不要使用一个大的总接口. 接口应该是内聚的,应该避免"胖"接口.一个类对另

小菜学设计模式——迪米特原则

背景 本文标题为什么叫小菜学习设计模式,原因是本文内容主要是学习<大话设计模式>时的笔记摘要部分,当然,并不是记录书中小菜的学习过程,这个完全没有意义,而是指本人学习设计模式的成长之旅. 真诚的希望自己能够从一名小菜成长为一名大鸟! 编写的程序应该满足: 1)可维护 2)可扩展 3)可复用 4)够灵活 废话少说,言归正传,设计模式原则之:迪米特原则(最少知识原则) 书面理解 迪米特原则:如果两个类不必彼此直接通信,那么这两个类就应当发生直接的相互作用.如果其中一个类需要调用另一个类的某一个方法

小菜学设计模式——里氏替换原则

背景 本文标题为什么叫小菜学习设计模式,原因是本文内容主要是学习<大话设计模式>时的笔记摘要部分,当然,并不是记录书中小菜的学习过程,这个完全没有意义,而是指本人学习设计模式的成长之旅. 真诚的希望自己能够从一名小菜成长为一名大鸟! 编写的程序应该满足: 1)可维护 2)可扩展 3)可复用 4)够灵活 废话少说,言归正传,设计模式原则之:里氏替换原则 书面理解 里氏替换原则:一个软件实体如果使用的是父类的话,那么一定适用与其子类,而且它察觉不出父类对象和子类对象的区别.也就是说,在软件里面,把

小菜学设计模式——高内聚、低耦合

背景 本文标题为什么叫小菜学习设计模式,原因是本文内容主要是学习<大话设计模式>时的笔记摘要部分,当然,并不是记录书中小菜的学习过程,这个完全没有意义,而是指本人学习设计模式的成长之旅. 真诚的希望自己能够从一名小菜成长为一名大鸟! 编写的程序应该满足: 1)可维护 2)可扩展 3)可复用 4)够灵活 废话少说,言归正传,设计模式原则之:高内聚.低耦合 当然,这条原则不是面向接口编程的具体原则,他是所有原则.所有设计模式都必须遵循的一条亘古不变的宗旨. 网上学习与记录 起因:模块独立性指每个模

小菜学设计模式——依赖倒转原则

背景 本文标题为什么叫小菜学习设计模式,原因是本文内容主要是学习<大话设计模式>时的笔记摘要部分,当然,并不是记录书中小菜的学习过程,这个完全没有意义,而是指本人学习设计模式的成长之旅. 真诚的希望自己能够从一名小菜成长为一名大鸟! 编写的程序应该满足: 1)可维护 2)可扩展 3)可复用 4)够灵活 废话少说,言归正传,设计模式原则之:依赖倒转原则 书面理解 依赖倒转原则: A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象. B.抽象不应该依赖于具体,具体应该依赖于抽象. 简单

小菜学设计模式——开放封闭原则

背景 本文标题为什么叫小菜学习设计模式,原因是本文内容主要是学习<大话设计模式>时的笔记摘要部分,当然,并不是记录书中小菜的学习过程,这个完全没有意义,而是指本人学习设计模式的成长之旅. 真诚的希望自己能够从一名小菜成长为一名大鸟! 编写的程序应该满足: 1)可维护 2)可扩展 3)可复用 4)够灵活 废话少说,言归正传,设计模式原则之:开放封闭原则 书面理解 开放封闭原则:软件实体(类.模块.函数等等)应该可以扩展,但是不可以修改 对于扩展是开放的,对于修改则是关闭的 无论模块是多么的封闭,

小菜学设计模式——设计模式总结之结构型

1.设计模式总结 设计模式总共23个,但是常用的不到10个,下面就把这23个设计模式进行整理归类,具体如下: 1)创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 2)结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 3)行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代器模式.职责链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式 2.结构型设计模式 1)适配器模式:将一个类的接口