设计模式(java) 单例模式 单例类
·单例类
单实例类,就是这个类只能创建一个对象,保证了对象实例的唯一性。
1.单例模式( Singleton Pattern) 是一个比较简单的模式, 其定义如下:
Ensure a class has only one instance, and provide a global point of access to it.( 确保某一个类
只有一个实例, 而且自行实例化并向整个系统提供这个实例。 )
1.1单例模式通用代码
public class Singleton {
private static final Singleton singleton = new Singleton();
//限制产生多个对象
private Singleton(){
}
//通过该方法获得实例对象
public static Singleton getSingleton(){
return singleton;
}
//类中其他方法, 尽量是static
public static void doSomething(){
}
}
2.单例模式实例
/*静态方法是属于类的,内存必须为它分配内存空间,这个空间一直由静态方法占用,
* 内存管理器不会由于静态方法没有被调用而将静态方法的存储空间收回,
* 这样如果将所有的方法都声明为静态方法,就会占用大量的内存空间,最后是系统变慢。
* 而普通的成员方法是由对象调用的,内存并不会一直为其分配内存,只有调用的时候才为其分配存储空间,
* 而当其没有被调用时,存储空间就会被内存管理其收回, 释放没有用的空间,提高的系统的运行速率!*/
class Singleton
{
private static Singleton instance; //使用static修饰,因为它要在该类的静态方法(getInstance)中被访问,作用是一个引用变量指向对象。 private Singleton(){}; //提供一个私有访问权限的构造方法,禁止外部创建对象,限制产生多个对象。 //方法必须是public的和static的,因为方法要公开被类SingletonTest调用并且 s1引用变量获取方法的方式是通过类.方法来实现的。<br> // 类的构造方法是私有的,所以外部类无法创建对象,所以用类.方法得到对象,这样就约束了创建对象的个数。
public static Singleton getInstance()
{
if (instance == null)
{
instance = new Singleton(); //自行实例化(在Singleton中自己使用new Singleton())
} return instance;
}
// 类中其他方法,尽量是static
public static void say(){
System.out.println("我是独一无二的");
}
} public class SingletonTest
{
public static void main(String[] args)
{
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
s1.say();
s2.say();
System.out.println(s1 == s2); //结果为true,这里可以看出确实是同一个对象 "=="比较两个对象的内存地址是否相同。
}
}
大臣与皇帝,大臣每天拜访皇帝一次:
public class Emperor {
private static final Emperor emperor = new Emperor();//初始化一个皇帝
private Emperor(){ }
public static Emperor getInstance(){
return emperor ;
}
// 皇帝发话了
public static void say(){
System.out.println("我就是皇帝某某");
}
} public class Minister { @SuppressWarnings("static-access")
public static void main (String[] args){
for(int day=0; day<3;day++){
Emperor emperor = Emperor.getInstance();
System.out.println("第"+(day+1)+"天");
emperor.say();
}
} }
特殊情况
升级版 固定数量的皇帝类
public class Emperor{ //定义最多能产生的实例的数量
private static int maxNumOfEmperor = 2;
// 每个皇帝都有名字, 使用一个ArrayList来容纳,每个对象的私有属性(如名字)
private static ArrayList<String> nameList = new ArrayList<String>();
// 定义一个列表,容纳所有的皇帝实例。
private static ArrayList<Emperor> emperorList = new ArrayList<Emperor>();
//当前皇帝序列号
private static int countNumOfEmperor = 0;
// private static Emperor emperor=
//产生所有的对象
//static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法
static{
for (int i = 0; i < maxNumOfEmperor; i++) {
//调用构造方法,构造一个皇帝对象,并把皇帝对象保存到emperorList中,
emperorList.add(new Emperor("皇"+(i+1)+"帝"));
}
}//虽然产生了两个皇帝 ,但是使用static让然体现了“单”(一次产生两个皇帝)
private Emperor() {
// TODO Auto-generated constructor stub
}
//通过传入皇帝名称,可以构造一个皇帝对象,并把皇帝对象的属性(名称)保存到nameList中,
private Emperor(String name) {
// TODO Auto-generated constructor stub
nameList.add(name);
}
//随机获取一个皇帝对象
public static Emperor getInstance(){
Random random = new Random();
//随机拉出一个皇帝,
countNumOfEmperor = random.nextInt(maxNumOfEmperor);
return emperorList.get(countNumOfEmperor); }
// 皇帝发话了
public static void say(){
System.out.println(nameList.get(countNumOfEmperor));
} }
public class Minister{
public static void main(String[] args) {
//定义5个大臣
int ministerNum = 5;
for (int i = 0; i < ministerNum; i++) {
Emperor emperor = Emperor.getInstance();
System.out.print("第"+(i+1)+"个大臣参拜的是:");
emperor.say(); }
}
}
3.单例模式的特点
(1)、单例类确保自己只有一个实例。
(2)、单例类必须自己创建自己的实例。
(3)、单例类必须为其他对象提供唯一的实例。
4.1单例模式的优点
● 由于单例模式在内存中只有一个实例, 减少了内存开支, 特别是一个对象需要频繁地
创建、 销毁时, 而且创建或销毁时性能又无法优化, 单例模式的优势就非常明显。
● 由于单例模式只生成一个实例, 所以减少了系统的性能开销, 当一个对象的产生需要
比较多的资源时, 如读取配置、 产生其他依赖对象时, 则可以通过在应用启动时直接产生一
个单例对象, 然后用永久驻留内存的方式来解决( 在Java EE中采用单例模式时需要注意JVM
垃圾回收机制) 。
● 单例模式可以避免对资源的多重占用, 例如一个写文件动作, 由于只有一个实例存在
内存中, 避免对同一个资源文件的同时写操作。
● 单例模式可以在系统设置全局的访问点, 优化和共享资源访问, 例如可以设计一个单
例类, 负责所有数据表的映射处理。
4.2单例模式的缺点
● 单例模式一般没有接口, 扩展很困难, 若要扩展, 除了修改代码基本上没有第二种途
径可以实现。 单例模式为什么不能增加接口呢? 因为接口对单例模式是没有任何意义的, 它
要求“自行实例化”, 并且提供单一实例、 接口或抽象类是不可能被实例化的。 当然, 在特殊
情况下, 单例模式可以实现接口、 被继承等, 需要在系统开发中根据环境判断。
● 单例模式对测试是不利的。 在并行开发环境中, 如果单例模式没有完成, 是不能进行
测试的, 没有接口也不能使用mock的方式虚拟一个对象。
单例模式与单一职责原则有冲突。 一个类应该只实现一个逻辑, 而不关心它是否是单
例的, 是不是要单例取决于环境, 单例模式把“要单例”和业务逻辑融合在一个类中。
设计模式(java) 单例模式 单例类的更多相关文章
- Java基础--单例类创建和测试
单例模式的主要作用是保证在Java程序中,某个类只有一个实例存在.单例模式有很多好处,它能够避免实例对象的重复创建,不仅可以减少每次创建对象的时间开销,还可以节约内存空间:能够避免由于操作多个实例导致 ...
- 《Effective Java》 读书笔记(三) 使用私有构造方法或枚举实现单例类
1.单例类到现在为止算是比较熟悉的一种设计模式了,最开始写单例模式是在C#里面,想要自己实现一个单例类,代码如下: public class Instance { private static rea ...
- 如何防止JAVA反射对单例类的攻击?
在我的上篇随笔中,我们知道了创建单例类有以下几种方式: (1).饿汉式; (2).懒汉式(.加同步锁的懒汉式.加双重校验锁的懒汉式.防止指令重排优化的懒汉式); (3).登记式单例模式; (4).静态 ...
- Java单例类的简单实现
对于java新手来说,单例类给我的印象挺深,之前一道web后台笔试题就是写单例类.*.*可惜当时不了解. 在大部分时候,我们将类的构造器定义成public访问权限,允许任何类自由创建该类的对象.但在某 ...
- java的单例设计模式
java的单例设计模式包括:饿汉设计模式和懒汉设计模式: 步骤: 1.创建一个对象把他设置为私有的成员变量,保证唯一 2.私有构造方法,防止new一个对象. 3.定义一个公开的静态方法,返回第一步创建 ...
- 【java设计模式】之 单例(Singleton)模式
1. 单例模式的定义 单例模式(Singleton Pattern)是一个比較简单的模式.其原始定义例如以下:Ensure a class has only one instance, and pro ...
- Java 之单例设计模式
设计模式: 对问题行之有效的解决方式, 其实它是一种思想. 单例设计模式 解决的问题:就是可以保证一个类在内存中的对象唯一性. 即单个实例. 比如对于A 和 B 两个程序使用同一个配置信息对象时, A ...
- 设计模式——懒汉式单例类PK饿汉式单例类
前言 我们都知道生活中好多小软件,有的支持多IP在线,有的仅仅局限于单个IP在线.为什么这样设计,在软件开发阶段就是,有需求就是发展.这就是软件开发的一个设计模式--懒汉式单例类和饿汉式单例类. 内容 ...
- Java设计模式:Singleton(单例)模式
概念定义 Singleton(单例)模式是指在程序运行期间, 某些类只实例化一次,创建一个全局唯一对象.因此,单例类只能有一个实例,且必须自己创建自己的这个唯一实例,并对外提供访问该实例的方式. 单例 ...
随机推荐
- HTML5 模拟现实物理效果,感受 Web 技术魅力
Ball Pool 是一个基于 HTML5 技术的实验,模拟现实物理效果,让你在 Web 中感受自然物体的运动.玩法介绍:可以随意拖动圆球.点击页面背景.晃动浏览器.双击页面背景或者按住鼠标左键,有不 ...
- Welcome Phalcon
Welcome! 欢迎来到 Phalcon 框架, 一种崭新的 PHP 框架.我们的使命是给开发者一个开发 web 站点和应用的高级工具,让开发者不用担心框架的性能问题. Phalcon 是什么? P ...
- css3中的animation
不使用js或jquery,用css3实现一张图片的滑动.我用的是animation来设置所要应用的动画效果,首先在html中写好一个<div></div>,并放置一张图片在di ...
- ABAP 动态生成内表的几种方法
最近要写个程序,既有更新的,也有删除的,需要涉及到很多系统表,如果一个表一个表进行更新或者删除太慢了,于是就想通过创建动态内表来实现这些功能,在网上找了一些资料,经过多次尝试,终于测试成功了.网上讲述 ...
- JEPF 3.1.2 发布,我们的软件机床(软件快速开发平台)
JEPF新一代软件快速开发平台(Java Elephant Platform)是一款优秀的平台产品,它本着灵活.快捷开发.高性能.高协作性.高稳定性.高可用性.人性化的操作体验为设计宗旨历经2年研发成 ...
- 如何在Infraworks中创建多树种组成的森林
在Infraworks 2014中,你可以有shp文件导入生成树木和森林,也可以直接在模型中规划一片区域作为森林.美中不足的就是,这些充其量叫树林不能叫森林,因为他们的样式都是一个树种,而真正的森林肯 ...
- Sharepoint学习笔记—习题系列--70-576习题解析 -(Q59-Q62)
Question 59You are designing a collection of Web Parts that will be packaged into a SharePoint 2010 ...
- 源码详解openfire保存消息记录_修改服务端方式
实现openfire消息记录通常有两种方式,修改服务端和添加消息记录插件. 今天,简单的说明一下修改服务端方式实现消息记录保存功能. 实现思路 修改前: 默认的,openfire只提供保存离线记录至o ...
- XMPP学习——3、XMPP协议学习补充
流基础 两个基本概念,使得XMPP实体之间的小的结构化信息有效载荷能快速地进行异步交换:XML流和XML节.这些术语的定义如下. XML流的定义: XML流是一个容器,用于任何两个实体通过网络进行XM ...
- 操作系统开发系列—13.h.延时操作
计数器的工作原理是这样的:它有一个输入频率,在PC上是1193180HZ.在每一个时钟周期(CLK cycle),计数器值会减1,当减到0时,就会触发一个输出.由于计数器是16位的,所以最大值是655 ...