`
liuwei1981
  • 浏览: 752707 次
  • 性别: Icon_minigender_1
  • 来自: 太原
博客专栏
F8258633-f7e0-30b8-bd3a-a0836a5f4de5
Java编程Step-by...
浏览量:156200
社区版块
存档分类
最新评论

71.利用static来实现单例模式

 
阅读更多

所谓设计模式(Design Pattern),是为了满足对优秀、简单而且可重用的解决方案的需要。这就像我们在盖楼的时候,我们不会每次都从零开始来画图纸,而是参照某种已有的模式,然后在此基础上来设计它。而在面向对象程序设计中,“模式”是为了实现重用面向对象代码的一种方便做法。


根据“设计模式”的经典著作《Design Patterns:Elements of reusable Object-Oriented software》中所述,设计模式一般包含四个基本要素:
1.模式名称(pattern name):一个助记名,用几个词汇来描述模式的问题、解决方案以及效果。
2.问题(problem):描述了应该在何时使用模式。
3.解决问题的方案(solution):描述了设计的组成部分,它们之间的相互关系及各自的职责和协作方式。
4.效果(consequences):描述了模式应用的效果及使用模式应权衡的问题。

 

我们现在来考虑单子(Singleton)设计模式的需求背景。

 

在实际应用中,我们可能需要限制生成的对象个数只能为1个。比如,在开发图形应用的时候,在菜单栏上按下“帮助”菜单,将弹出一个帮助对话框,也就是生成了一个帮助对话框的实例,如果对话框已经出现,则即使再在菜单栏上按下“帮助”菜单,应用程序也不应该再生成新的对话框实例。这个时候,如果还是通过原来的用构造器来生成实例的方式,很难对其生成的实例个数进行控制。通过所谓的“单子设计模式”,可以实现这个功能。

单子设计模式的基本思路是在类的内部定义一个静态变量,当创建第一个实例时设置该变量。应用程序直接使用这个静态变量指向的实例就可以了。为了防止应用程序调用构造器来新建实例,必须限制构造器的访问,也就是将它的访问控制设置为“private”。


概括起来,要实现“单子设计模式”,可以利用下面的方式来完成:
创建一个类,满足:
构造器私有;
用一个私有、静态变量引用实例;
提供一个公有、静态方法获得实例。

 

 

 

下面来看一个这个实现的例子:

 

 

public class SingletonPattern {
 private double r;

 // 定义一个私有、静态的引用变量
 private static SingletonPattern sp;

 // 构造器私有
 private SingletonPattern() {
  r = java.lang.Math.random();
 }

 // 提供一个公有、静态方法获得唯一实例
 public static SingletonPattern getInstance() {
  if (sp == null)// 如果还未创建实例
  {
   sp = new SingletonPattern();// 则创建一个实例
  }
  return sp;// 将它返回
 }

 public double getR() {
  return r;
 }

 public static void main(String args[]) {
  SingletonPattern sp1 = SingletonPattern.getInstance();
  SingletonPattern sp2 = SingletonPattern.getInstance();
  System.out.println(sp1.getR());
  System.out.println(sp2.getR());
 }
}


在这个例子中,我们利用上面所讨论的方法实现了“单子设计模式”,为了简单的测试我们每次得到的对象是否为同一个对象,我们在构造器中给该类的实例变量r赋了一个随机的值。如果每次得到的实例是同一个,那么,它的实例变量r的值也必定相同。

 

为了测试这个类,在这个类中定义了一个main()方法,然后通过SingletonPattern类的静态方法getInstance()来获得两个SingletonPattern实例,分别赋给两个引用变量sp1和sp2,然后通过这两个实例的getR()方法将它的实例变量打印出来。运行上面的程序,可以得到类似如下的输出:
0.04960654267464748
0.04960654267464748


这说明,这两个引用变量指向的是同一个实例,也就是只有一个实例存在。因为这个类的构造器被定义为“private”,所以不能直接调用它的构造器来生成新的实例,这也就避免了通过直接调用构造器生成多个实例的情况。

分享到:
评论
1 楼 yehui18sui 2014-05-23  
不错,在项目中却一直没有用到,学一遍忘一遍

相关推荐

    [创建型模式] 单例模式(Singleton Pattern)

    一个类可以创建多个对象,这是面向对象的语言特性,想要实现单例模式,就要屏蔽这个特性,防止系统可以随意创建类的对象。 要做到这一点,通常做法就是利用private关键字将类的构造方法私有化,使外部调用者无法利用...

    Java单例模式实现

    我们利用Java关键字static特性,在类初始化就被加载,并在以后的加载中不再加载。 /** * 饿汉模式,静态成员变量 * * @author justLym * @version 1.0.0 2020/3/13 18:58 **/ public class StaticInstance { ...

    二十三种设计模式【PDF版】

    设计模式之 Singleton(单态/单件) 阎宏博士讲解:单例(Singleton)模式 保证一个类只有一个实例,并提供一个访问它的全局访问点 设计模式之 Factory(工厂方法和抽象工厂) 使用工厂模式就象使用 new 一样频繁. ...

    代码生成器-可自定义模版-guns

    系统地讲解了如何构建一个日常生产环境...10. 页面统一的js key-value单例模式写法,每个页面生成一个唯一的全局变量,提高js的利用效率,并且有效防止多个人员开发引起的函数名/类名冲突,并且可以更好地去维护代码

    【05-面向对象(下)】

    把基本数据类型变量包装类实例是通过对应包装类的构造器来实现的,不仅如此,8个包装类中除了 Character之外,还可以通过传入一个字符串参数来构建包装类对象。 •如果希望获得包装类对象中包装的基本类型...

    最新JAVA编程题全集_50题及答案

    写一个单例模式(遇到两次) public class Test { private Test(){} private static Test test; public static Test getInstance() { if(test==null) { test = new Test(); } return test; }} 5. //统计...

    java 面试题 总结

    HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。 HashMap允许将null作为一个entry的key或者...

    超级有影响力霸气的Java面试题大全文档

    HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。 HashMap允许将null作为一个entry的key或者...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part1

    实例206 弹出全屏显示的网页模式对话框 261 实例207 关闭IE主窗口时不弹出询问对话框 262 实例208 弹出提示对话框并重定向网页 263 实例209 自动关闭的广告窗口 264 实例210 在弹出的对话框中选择个性头像 265 实例...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part2

    实例206 弹出全屏显示的网页模式对话框 261 实例207 关闭IE主窗口时不弹出询问对话框 262 实例208 弹出提示对话框并重定向网页 263 实例209 自动关闭的广告窗口 264 实例210 在弹出的对话框中选择个性头像 265 实例...

Global site tag (gtag.js) - Google Analytics