zoukankan      html  css  js  c++  java
  • 浅谈单例模式及其java实现

      单例模式是23种设计模式中比较简单的一种,在此聊一下单例模式。

    1.什么是设计模式?

      对于没有接触过设计模式的人来说,一听到设计模式这四个字就觉得这个东西很高深莫测,一下子就对这个东西产生了恐惧感,其实设计模式是那些大佬在项目经验中领悟出来并总结出来的套路,这些套路能够用于应对项目开发中的特定问题,所以设计模式并不可怕(其实心里慌得一批。。。)。设计模式一共有23种,根据用途来分类,可分为三类:

    • 创建型模式:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式
    • 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元 模式、代理模式
    • 行为型模式:模板访问模式、命令模式、迭代模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、责任链模式、访问者模式

    2.单例模式的作用

    保证一个类只有一个实例,并且提供访问该实例的全局访问点

    3.单例模式的应用场景

    • Windows的Task Manager(任务管理器)就是很典型的单例模式
    • windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。
    • 项目中,读取配置文件的类,一般也只有一个对象。没有必要每次使用配置文件数据,每次new一个对象去读取。
    • 网站的计数器,一般也是采用单例模式实现,否则难以同步。
    • 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
    • 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。
    • 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。
    • Application 也是单例的典型应用(Servlet编程中会涉及到)
    • 在Spring中,每个Bean默认就是单例的,这样做的优点是Spring容器可以管理
    • 在servlet编程中,每个Servlet也是单例
    • 在spring MVC框架/struts1框架中,控制器对象也是单例

    4.单例模式的实现方式(java)

    4.1 饿汉式

     1 package Singleton;
     2 /**
     3  * 饿汉式单例模式
     4  * @author cjj
     5  */
     6 public class Singleton01 {
     7     //在静态属性中创建实例
     8     private static Singleton01 instance=new Singleton01();
     9     //私有化构造器
    10     private Singleton01() {}
    11     //返回实例
    12     public static Singleton01 getInctance() {
    13         return instance;
    14     }
    15 }

    为啥这种实现方式称为饿汉式呢?因为这种实现方式是在静态属性中创建实例的,静态属性在类加载的时候就已经创建好实例了,这个时候还没有开始使用实例呢,所以很形象地称之为饿汉式实现(手动狗头程序员并不都是无趣的动物。。。),所以这种实现方式会造成内存的损耗。

    4.2 懒汉式

     1 package Singleton;
     2 /**
     3  * 懒汉式单例模式
     4  * @author cjj
     5  *
     6  */
     7 public class Singleton02 {
     8         //私有化构造器
     9     private Singleton02() {
    10     }
    11     private static Singleton02 instance;
    12     public static synchronized Singleton02 getInstance() {
    13         if(instance!=null) {
    14             instance=new Singleton02();
    15         }
    16         return instance;
    17     }
    18 }

    饿汉式的鲜明对比是懒汉式,这种实现方式是在调用时才创建实例。用买车票的比喻来说明这两种实现方式,饿汉式是属于那种第二天才出行,它在前一天就已经预定好车票了,而懒汉式这个家伙呢,在汽车出发前一分钟才买好票。与饿汉式相比,这种实现方式似乎比较合理,however,这种实现方式解决了饿汉式的缺点,也带来新的问题——会造运行速度慢一些。正所谓“没有最好的算法,只有适合的算法,空间复杂度与时间复杂度难两全!”

    4.3 静态内部类创建实例

     1 package Singleton;
     2 
     3 /**
     4  * 用静态内部创建实例
     5  * @author cjj
     6  *
     7  */
     8 public class Singleton04 {
     9     
    10     //用静态内部类来创建实例
    11     static class SingleInstance{
    12         public static final Singleton04 instance=new Singleton04();
    13     }
    14     //私有化构造器
    15     private Singleton04() {}
    16     //返回实例
    17     public static Singleton04 getInstance() {
    18         return SingleInstance.instance;
    19     }
    20     
    21 }

    这种实现方式结合了饿汉式和懒汉式两种方法的优点,即调用时加载类(静态内部类)并创建实例。

    4.4枚举型创建单例

    1 package Singleton;
    2 
    3 public enum Singleton05 {
    4     INSTAANCE;
    5     public void Operation() {
    6         
    7     }
    8 }

    这种创建方式简单明了,在枚举类中设计就只有一个实例INSTAANCE,然后添加单例的操作就可以了,补充一下枚举型本质上也是属于一种类,每个枚举型都继承于java.lang.Enum<>类,所以枚举型也可以有成员方法的。这种方法避免了运用反射调用私有构造器来创建实例。

  • 相关阅读:
    android一些细节问题
    Android Suspend/resume 过程分析.
    在NDK上建立自己的项目
    ListView加载特效
    Android Log Analysis转
    Android系统默认设置
    一步步分析Log
    Android Framework 分析
    编译安装MariaDB10.0.21
    mariadb多源复制 muiltil source replication
  • 原文地址:https://www.cnblogs.com/ironHead-cjj/p/11306043.html
Copyright © 2011-2022 走看看