《研磨设计模式》中的定义:保证一个类仅有一个实例,并提供它的一个全局访问点。

而单例模式的本质便是——控制实例数目。

一、介绍

1、单例模式和静态方法区别

简单的一个懒汉式单例模式

public class EagerSingleton {private static EagerSingleton instance = new EagerSingleton();/*** 私有默认构造子*/private EagerSingleton(){}/*** 静态工厂方法*/public static EagerSingleton getInstance(){return instance;}
}

静态方法

class Test{public static int z(int xx,int yy){return xx+yy;}public int zz(int xx,int yy){return xx+yy;}
}

调用对比

public static void main(String args[]){// 调用静态方法sum=Test.z(1,2); // 调用非静态方法Test t=new Test();sum=t.zz(1,2); // 调用单例模式EagerSingleton instance = EagerSingleton.getInstance();
}

1、单例模式

  关于单例模式的概念这里不再多说,单例模式的好处有如下几个:

  1)只有一个实例对象,节省内存空间

  2)支持延迟加载

  3)由于单例对象一般用static修饰,所以一次创建长久使用,即不会被GC回收

2、静态方法

  相对于单例模式,静态方法的优势如下:

  1)没有实例对象,直接使用方法

  2)速度更快

  但静态方法也有劣势:

  1)不能延迟加载,JVM启动时自动加载static修饰的对象

  2)耦合性强,这里所说的耦合性强是指静态方法无法被重写,因为重写是针对非静态方法而言,当方法需要变更的时候必须进行修改操作,违反了开闭原则。可能有的童鞋没有理解,举例言之,接口A是我们的dao层方法规范,我们通过实现类A1来完善方法功能,如果有变更,可以新建一个实现类或A1的子类A2来完成,此时调用方不需要做任何的更改;而如果使用静态方法,则需要修改调用方

  3)事务控制更加麻烦,我们在用spring做事务控制的时候是基于AOP实现的,其原理是使用JDK的动态代理或者cglib来实现,不管使用哪一种,都需要一个实例对象来创建代理对象,而使用静态方法时由于没有实例对象,所以也就无法使用这种声明式事务了

3、总结

  个人推荐优先使用单例模式,那么什么时候使用静态方法呢?对于一个类,满足单例情况且不会出现上面所说的耦合性和事务问题即可使用静态方法,如java中的Math类。我刚接手的项目中是对redis的一个简单查询功能,满足上述的情况,所以也适用静态方法来实现。

单例模式介绍

1、单例模式是比较简单的模式,传统的有懒汉式和饿汉式两种。

懒汉式如下:

public class Singleton1 {private static Singleton1 instance = null;private Singleton1() {}public static Singleton1 getInstance() {if (instance == null) {instance = new Singleton1();}return instance;}
}

顾名思义,懒汉式便是类加载时并不创建该单例对象实例,等到类使用时才去创建。

2、饿汉式如下:

public class Singleton2 {private static Singleton2 instance = new Singleton2();private Singleton2() {}public static Singleton2 getInstance() {return instance;}
}

  

饿汉式便是类加载时便创建实例了,故每次使用时无需创建。

懒汉式、饿汉式就是Spring中的BeanFactory和ApplicationContext在处理单例类时的区别。

3、由于懒汉式单例模式并非线程安全的,想要保证线程安全,除了在创建实例的方法上加Synchronized之外,最简单的当然是,在创建对象的时候,每一步多进行一次判断,判断该对象是否已经存在。

二、优雅实现

然而,《研磨设计模式》中介绍了Java中一种一优雅的,能保证线程安全的懒汉式单例模式,叫做Lazy initialization holder class模式。如下:

public class Singleton3 {private Singleton3() {}private static class SingletonHolder {private static Singleton3 instance = new Singleton3();}public static Singleton3 getInstance() {return SingletonHolder.instance;}
}

  

类的静态内部类,实际上是一个顶层类,可以不依赖外围类的实例而存在,就像是类的一个静态成员变量。只有在使用时,其内部的变量才会被实例化。Lazy initialization holder class模式便是利用JVM自身的特性保证了线程安全。

三、推荐使用

枚举类型

public enum User {/*** 单例*/Instance;private User() {System.out.println("初始化User");}public void print() {System.out.println("tttttt");}
}

调用

User user = User.Instance;
String code = user.getCode();

使用枚举来实现单实例控制会更加简洁,而且无偿地提供了序列化机制,并由JVM从根本上提供保障,绝对防止多次实例化,是更简洁、高效、安全的实现单例的方式。
你可以通过EasySingleton.INSTANCE来访问,这比调用getInstance()方法简单多了。

优点:
1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
2、避免对资源的多重占用(比如写文件操作)。
缺点:
1、没有接口,不能继承,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
2、通过控制自己的创建和生命周期,违反了单一责任原则SRP(Single Responsibility Principle)
3、创建紧密耦合的代码,单例模式的客户端变得难以测试
总结:
使用单例模式考虑线程安全和性能,推荐使用静态内部类 和 枚举

转载于:https://www.cnblogs.com/JiangWJ/p/10807764.html

创建型设计模式 之 单例模式相关推荐

  1. 创建型设计模式(单例模式)

    单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 一.懒汉式单例 //懒汉式单例类.在第一次调用的时候实例化自己 p ...

  2. 设计模式--创建型设计模式

    一. 设计模式的目的 ​ 编写软件过程中,可能面临来自耦合性.内聚性.可维护性.可扩展性.重用性.灵活性等多方面的挑战,设计模式是为了让程序具有更好的: 代码重用性(即相同的代码,不用多次编写) 可读 ...

  3. 设计模式----创建型设计模式(单例模式、工厂方法模式、构建者模式)

    创建型设计模式 单例模式(Singleton Pattern) 单例模式介绍 代码演示 饿汉式(静态常量) 饿汉式(静态代码块) 懒汉式(线程不安全) 懒汉式(线程安全,同步方法) 懒汉式(线程安全, ...

  4. 技术图文:02 创建型设计模式(下)

    创建型设计模式(下) 知识结构: 图1 知识结构 单例模式 – 确保对象的唯一性 Sunny 软件公司承接了一个服务器负载均衡软件的开发工作,该软件运行在一台负载均衡服务器上,可以将并发访问和数据流量 ...

  5. 创建型设计模式对比总结 设计模式(八)

    创建型模式是new 的一种替代方式,可以将对象的创建与具体的类型进行分离 目前已经介绍了5种创建型设计模式(如果简单工厂算一种的话,那就是6种) 分别是: 简单工厂模式.工厂方法模式.抽象工厂模式.建 ...

  6. java面向对象程序设计第三版_JAVA面向对象程序设计之创建型设计模式

    [本文详细介绍了JAVA面向对象程序设计中的创建型设计模式,欢迎读者朋友们阅读.转发和收藏!] 1 基本概念 1.1 什么是设计模式 设计模式( Design pattern )是一套被反复使用.多数 ...

  7. 从框架源码中学习创建型设计模式

    文章目录 从框架源码中解读创建型设计模式 工厂模式 案例一:RocketMQ源码-创建Producer生产者 案例二:RocketMQ源码-创建过滤器工厂 抽象工厂 案例一:Dubbo源码-创建缓存的 ...

  8. java设计模式之创建型设计模式

    创建型设计模式: 抽象工厂(Abstract Factory): 用途:提供一个接口以创建一系列相关或相互依赖的对象,而无需指定具体的类. 场景: 一个系统要独立于它的产品的创建. 一个系统要由多个产 ...

  9. JavaScript设计模式之创建型设计模式

    此系列总结与<JavaScript设计模式>,总共分为创建型设计模式.结构型设计模式.行为型设计模式.技巧型设计模式和架构性设计模式五大类. github原文地址:YOU-SHOULD-K ...

最新文章

  1. 什么叫通过超链接实现换页_亚马逊大卖都在用的那些链接 -- 超链接
  2. matlab 不单调 插值,三组无关数据进行MATLAB画三维图不采用插值的方法该怎么办...
  3. linux下安装配置DHCP服务器
  4. NLPPython笔记——WordNet
  5. 国自然和毕业论文的流程图用这个格式导入Word可无限放大
  6. mysql创建视图sql_SQL视图介绍-如何在SQL和MySQL中创建视图
  7. Android学习笔记:短信控制手机之“短信开启定位”
  8. SharePoint 站点出现Http 503 错误
  9. skyeye + ulibc + busybox + linux kernel
  10. NLP简报(Issue#6)
  11. LinkedList常用方法笔记
  12. 最新Activity与Fragment完全理解
  13. 耗费两小时整理电子入行学习资源
  14. golang爬取Instagram内容下载地址
  15. viper12a电源电路图_VIPer12A功率开关电源IC.pdf
  16. Python爬虫代理池搭建
  17. 对话海尔CEO张瑞敏
  18. 华易记账宝 v6.5
  19. 区块链进化论:极客与开源 - 区块链大航海时代
  20. 用服务器建立个人网站

热门文章

  1. 【Kali渗透全方位实战】利用Beef进行XSS会话劫持(XSS Stored)
  2. 修改数据无法提交_MySQL数据库精讲:一文讲解MySQL事务隔离!
  3. 如何提升网站在搜索引擎中的排名?
  4. 学计算机买笔记本是i5 i7,i7不一定比i5好!懂电脑的人选择买i5,而不是i7,究竟怎么回事?...
  5. 主题图片_临床医学院“树树皆秋色,山山唯落晖”主题图片征集活动
  6. 石嘴山考计算机在哪里报名,石嘴山中考报名系统
  7. 三年python面试题_300道Python面试题
  8. python刚开始学什么_刚入门的时候,你们都是怎么开始学Python的呢?
  9. jq选中单选框后文本框不可编辑_打开速度最快最强大的PDF免费工具,编辑+阅读功能一体...
  10. android 程序闪退 log,写了一个android小程序,测试的时候闪退,然鹅log并没有报错...