单例模式之自我介绍

  我,单例模式(Singleton Pattern)是一个比较简单的模式,我的定义如下:

  Ensure a class has only one instance,and provide a global point of access to it.(确保其某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。)单例模式的通用类图如下:

  

  Singleton类称为单例类,通过使用private的构造函数确保了在一个应用中只产生一个实例,并且是自行实例化的。

单例模式之自我分析

  做人,哦不,做模式不能自满,所以先谈谈我的缺点,我的缺点如下:

  • 我一般没有接口,扩展很困难,如果想扩展的话,除了修改代码基本上没有第二种方式。当然了,特殊情况下,我也可以实现接口、被继承等,这个需要你们自行判断。
  • 测试不便。在并行开发中,如果你们没有把我完成,那么是没有办法进行测试的。
  • 还有一点,我与单一职责原则也有冲突,一个类本应实现一个逻辑,不该关心是否是单例的,是不是要单例取决于环境,但是我把单例和业务逻辑融合在一个类中了。

  终于该说优点了~挺好了,比缺点可是要多的说:

  • 对唯一实例的受控访问。由于我的类封装了我唯一的实例,所以可以严格控制用户以及何时访问它。
  • 缩小名空间。我可以避免那些存储唯一实例的全局变量污染名空间。
  • 允许对操作和表示的精化。
  • 允许可变数目的实例。
  • 比类操作更灵活。

单例模式之实现

  俗话说,说的比唱的好听。为了证明我唱的也很好听,接下来我就以人类的一夫一妻制来具体讲解一下如何实现我的模式~一夫一妻制又称作”单偶婚“,“个体婚”,据说一夫一妻制起源于秦始皇统一天下之后,自大秦一统天下,中国酒实行了一夫一妻制,尤其是在汉朝“罢黜百家,独尊儒术”开始,古人严格执行了这一制度blablabla...(此处省略n字)。咳咳,跑题了,我们接着谈一夫一妻制,哦不,单例模式,首先得有个妻子类:

 1 public class Wife{
2
3 private static final Wife wife = new Wife();
4 private Wife(){
5
6 }
7 public static Wife getInstance(){
8 return wife;
9 }
10 public static void say(){
11 System.out.println("I am Y's wife!");
12 }
13 }

  通过定义一个私有访问权限的构造函数,可以避免被其他类new出来一个对象,而Wife自己可以new一个对象出来,其他的类对该类的访问可以通过getInstance获得一个对象。妻子有了,老公Y自然要出场了,其类代码如下:

1 public class Y{
2 public static void main(String[] args) {
3 for (int day=0; day<3;day++ ) {
4 Wife wife = Wife.getInstance();
5 wife.say();
6 }
7 }
8 }

  运行结果如下:

  I am Y's wife!

  I am Y's wife!

  I am Y's wife!

  Y每天回家见到的妻子,都是同一个妻子,不会出现开门后,一看,呦呵,老婆怎么变了?如有此情况,请速与我联系!

单例模式之优化OR问题

  有人嫌这样麻烦,因为无论是都使用这个类,都会创建一个instance对象,如果创建这个很耗时,比如需要连接10**9(python的10的9次方写法)次数据库,并且还不一定使用,那该这么办?于是乎有“聪明人”想到如下的方法: 

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

  是不是感觉很不错,很好?这个是传说中的懒汉模式其实这个有个很大的问题,如果是高并发情况下,可能A线程在创建实例,但是还没获取对象,B此时也在执行,判断也为真,所以又获得一个对象,如此下去,你的妻子会越来越多!没办法了么?不,当然有,且往下看:

 1 public class Singleton {
2 private static Singleton instance;
3 private Singleton (){}
4 public static synchronized Singleton getInstance() {
5 if (instance == null) {
6 instance = new Singleton();
7 }
8 return instance;
9 }
10 }

  这种写法确实解决了问题,但是效率么,啧啧,99%情况下不需要同步我会告诉你么?

奇淫技巧:单例模式之反射实现

 1 public class Singleton{
2 private static Singleton singleton;
3 static{
4 try{
5 class cl = class.forName(Singleton.class.getName());
6 //获得无参构造
7 Constructor con = cl.getDeclaredConstructor();
8 //设置无参构造是可访问的
9 con.setAccessible(true);
10 //产生一个实例对象
11 singleton = (Singleton)con.newInstance();
12 }
13 catch(Exception e)
14 {
15
16 }
17 }
18
19 public static Singleton getSingleton(){
20 return singleton;
21 }
22 }

  通过获得类构造,然后设置访问权限,生成一个对象,然后提供外部访问,保证内存对象单一。

设计模式之单例模式(JAVA实现)的更多相关文章

  1. 软件设计模式之单例模式(JAVA)

    什么是单例模式? 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系 ...

  2. GOF23种设计模式之单例模式(java)

    GOF(group of four):四人帮 分类 创建者模式 单例模式 核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点 优点: 由于单例模式只生成一个实例,减少了系统性能开销, ...

  3. java设计模式之单例模式(几种写法及比较)

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  4. java 23 - 2 设计模式之单例模式

    单例模式:保证类在内存中只有一个对象. 如何保证类在内存中只有一个对象呢?  A:把构造方法私有  B:在成员位置自己创建一个对象  C:通过一个公共的方法提供访问 单例模式之饿汉式: (一进来就造对 ...

  5. [转]JAVA设计模式之单例模式

    原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主 ...

  6. 设计模式 -- 单例模式(Java&&PHP)

    所谓单例模式,简单来说,就是在整个应用中保证只有一个类的实例存在.就像是Java Web中的application,也就是提供了一个全局变量,用处相当广泛,比如保存全局数据,实现全局性的操作等. 能够 ...

  7. java 设计模式之单例模式

    -------Success is getting what you want, happiness is wanting what you get. java设计模式之单例模式(Singleton) ...

  8. Java设计模式03:常用设计模式之单例模式(创建型模式)

    1.  Java之单例模式(Singleton Pattern ) 单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例.饿汉式单例.登记式单例三种. 单例模式有一下特点: 1.单例类只能有一个实 ...

  9. java设计模式之三单例模式(Singleton)

    单例对象(Singleton)是一种常用的设计模式.在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在.这样的模式有几个好处: 1.某些类创建比较频繁,对于一些大型的对象,这是一笔 ...

随机推荐

  1. [LintCode]转换字符串到整数

    问题描述: 实现atoi这个函数,将一个字符串转换为整数.如果没有合法的整数,返回0.如果整数超出了32位整数的范围,返回INT_MAX(2147483647)如果是正整数,或者INT_MIN(-21 ...

  2. 设置cookies第二天0点过期

    网上这个资料很少,试了csdn其中一个人的方法去算时间,返回的是Invalid Date,不知道是不是不同IE版本 返回结果不同 后面找到另外一个很简答粗暴的方法 直接加一天后,设置时分秒为0,代码如 ...

  3. EcmaScript对象克隆之谜

    先谈谈深拷贝 如何在js中获得一个克隆对象,可以说是喜闻乐见的话题了.相信大家都了解引用类型与基本类型,也都知道有种叫做深拷贝的东西,传说深拷贝可以获得一个克隆对象!那么像我这样的萌新自然就去学习了一 ...

  4. rails下mysql出错问题mysql_api,blog/text

    问题一:提示出错:cannot load such file -- mysql/mysql_api (LoadError) 此时我们回来看gem install mysql 时提示 At the ti ...

  5. kettle中执行sql语句

    一.直接执行sql,不添加任何参数 1.先找出执行sql语句的控件 2.打开控件,填写要执行的sql语句,主要下图中的红框中选项,后面会介绍各个选项的作用 二.执行sql,变量替换选项,变量指的是ke ...

  6. easyUI datagrid 排序

    easyUI datagrid 排序 1.首先设置datagrid属性sortName 2.设置sortOrder 3.设置remoteSort(注:此属性默认为true,如果如果是对本地数据排序必须 ...

  7. 【R】提升R代码运算效率的11个实用方法

    低.有许多种方法可以提升你的代码运算效率,但或许你更想了解运算效率能得到多大的提升.本文将介绍几种适用于大数据领域的方法,包括简单的逻辑调整设计.并行处理和Rcpp的运用,利用这些方法你可以轻松地处理 ...

  8. [android] Android 错误集锦

    问题1:导入工程时报错The import android.XXX cannot be resolved 解决方法: 1.右键工程→Bulid Path→Configure Build Path... ...

  9. Qt信号槽的一些事

    注:此文是站在Qt5的角度说的,对于Qt4部分是不适用的. 1.先说Qt信号槽的几种连接方式和执行方式. 1)Qt信号槽给出了五种连接方式: Qt::AutoConnection 0 自动连接:默认的 ...

  10. imx6 读取CPU温度

    imx6 读取CPU温度 cat /sys/class/thermal/thermal_zone0/temp Tony Liu 2017-2-11, Shenzhen