设计模式系列(一)单例模式

一、用通俗的语言解释其意义:从秦始皇之后确立了皇帝的位置,且同一时期只有一个。因此大家在称呼的时候不需要为皇帝加上其他的前缀。这一过程反应在设计领域就是,要求一个类只能生成一个对象,所有对象对他的依赖都是相同的,因为只有一个对象,所以对象对他的依赖都是相同的,因为只有一个对象,大家对他都很了解。皇帝每天要处理很多的事情,但是皇帝只有一个,即一个类只有一个对象,对象产生通过new关键字完成,我们可以使用构造函数来控制,因为使用new关键字创建对象时都会根据输入的参数调用相应的构造函数,所以如果我们将构造函数的访问权限设置为private就可以进制外部创建对象了。

将以上的情景设置为简单的例子:

皇帝类:

 1 public  class Emperor{
 2 private static final Emperor emperor=new Emperor();//初始化一个皇帝
 3 private Emperor(){
 4 }
 5 public static Emperor getInstance(){
 6 return emperor;
 7 }
 8 public static void say(){
 9 System.out.println("我的就是皇帝");
10 }
11 }

通过定义私有的访问权限的构造函数,避免被其他类new出一个对象,而Emperor自己则可以new一个对象处理,其他类都可以访问getInstance获得同一个对象。

大臣类:

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

二、单例模式的定义

单例模式(Singleton Pattern):Ensure class has only one instance,and provide a global point of access to it.

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

单例模式的通用代码:

1 public class Singleton{
2 private static final Singleton singleton=new Singleton();
3 private Singleton(){}
4 public static Singleton getSingleton(){
5 return singleton;
6 }
7 public static void doSomething(){}
8 }

三、单例模式的应用
1、单例模式的优点

由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁的创建和销毁时,而且创建或销毁的性能又无法优化,单例模式的优势就非常明显。

由于单例模式只生成一个实例,所以减少了系统的性能开销,当一个对象的产生需要较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。

单例模式可以避免对资源的多重占用,例如一个写文件动作,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。

单例模式可以在系统设置全局的访问点,优化和共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理。

2、单例模式的缺点

单例模式一般没有接口,扩展比较困难,若要扩展,除了修改没有第二个办法。单例模式为什么不能增加接口?因为接口对单例模式是没有任何意义的,他要求自行实例化,并且提供单一实例。接口或抽象类是不能被实例化的。

单例模式对测试是不利的,在单例模式没有完成之前,是不能进行测试的。

单例模式与单一职责原则是有冲突的,一个类应该只实现一个逻辑,而不关心她是否单例,是不是单例要取决于环境,单例模式将要单例和业务逻辑融合在一个类里。

3、单例模式的使用场景

要求生成唯一序列号的环境;

在整个项目中需要一个共享访问点或共享数据,例如一个web页面上的计数器,可以不用把每次刷新都记录到数据库中,使用单例模式爆出加护器的值,并确保线程安全。

创建一个对象需要消耗资源过多,如要访问IO和数据库等资源

需要定义大量的静态常量和静态方法如工具类等。

4、单例模式的注意事项

在高并发的情况下,要注意单例模式的线程同步问题

线程不安全的单例:

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

该单例模式在低并发的情况下是没有问题的,在并发增多时,则可能在内存中存在多个实例,破坏最初的预期。例如线程A执行到singleton=new Singleton()但是没有获得对象,此时第二个线程也开始判断平执行,解决线程不安全的方法很多,可以在getSingleton方法前面加上synchronized来实现;还要考虑对象的复制情况。在java中默认是不可以复制的,若实现的Clonable接口,并实现了clone方法则可以直接通过复制方式创建一个新对象,对象复制是不调用构造函数的,因此即使是私有构造函数依然可以复制。一般很少单例类会主动要求被复制,因此不要实现Clonable接口。
四、单例模式的扩展

我们之前看到的都是单例创建单一对象。如果要多于一个对象该如何。

固定数量的皇帝类:

 1 public class Emperor{
 2 //定义最多能产生的实例实例
 3 private static int maxNumOfEmperor=2;
 4 //每个皇帝都有名字,使用一个ArrayList来容纳,每个对象的私有属性
 5 private static ArrayList<String> nameList=new ArrayList<String>();
 6 //定义一个列表,容纳所有的皇帝实例
 7 private static ArrayList<Emperor> emperorList=new ArrayList<Emperor>();
 8 //当前皇帝序列号
 9 private static int countNumOfEmperor=0;
10 //产生所有的对象
11 static{
12 for(int i=0;i<maxNumOfEmperor;i++){
13 emperorList.add(new Emperor("皇"+i+"帝"));
14 }
15 }
16 private Emperor(){
17 }
18 private Emperor(String name){
19 nameList.add(name);}
20 public static Emperor getInstance(){
21 Random random=new Random();
22 countNumOfEmperor=random.nextInt(maxNumOfEmperor);
23 return emperorList.get(countNumOfEmperor);
24 }
25 public static void say(){
26 System.out.println(nameList.get(countNumOfEmperor));}
27
28 }

大臣类:

 1 public class Minister{
 2 public static void main(String[]args)
 3 {
 4 int ministerNum=5;
 5 for(int i=0;i<ministerNum;i++){
 6 Emperor emperor=Emperor.getInstance();
 7 System.out.println("第"+(i+1)+"个达成拜的是:");
 8 emperor.say();
 9 }
10 }
11 }

这种也叫作有上限的多例模式。

五、实践

在Spring中。每个Bean默认就是但离得,这样做的有点事Spring容器可以管理他们的生命周期,创建 销毁等。如果才有用非单例模式。则Bean初始化之后的管理交由J2EE容器,Spring容器不再跟踪管理Bean的生命周期。

时间: 2024-08-04 18:41:45

设计模式系列(一)单例模式的相关文章

23种设计模式系列之单例模式

本文继续介绍23种设计模式系列之单例模式. 概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.这些应用都或多或少具有资源管理器

设计模式系列之单例模式

单例模式是使用最广泛,也最简单的设计模式之一,作用是保证一个类只有一个实例.单例模式是对全局变量的一种改进,避免全局变量污染命名空间.因为以下几个原因,全局变量不能作为单例的实现方式: 1. 不能保证只有一个全局变量 2. 静态初始化时可能没有足够的信息创建对象 3. c++中全局对象的构造顺序是未定义的,如果单件之间存在依赖将可能产生错误 单例模式的实现代码很简单: //singleton.hpp #ifndef SINGLETON_HPP #define SINGLETON_HPP clas

[js高手之路]设计模式系列课程-单例模式实现模态框

什么是单例呢? 单,就是一个的意思.例:就是实例化出来的对象,那合在一起就是保证一个构造函数只能new出一个实例,为什么要学习单例模式呢?或者说单例模式有哪些常见的应用场景.它的使用还是很广泛,比如:弹出一个模态框,一般来说在网站中弹出的模态框,不停的一直点击,一般只能创建一个.还有后台的数据库连接,一般都是保证一个连接等等.今天的主题就是单例在模态框中的应用,我们先要搞清楚,怎么弄个单例出来. 我们先看下普通的构造函数加原型方式.下面这种是常见的方式 1 function Singleton

【设计模式系列】单例模式的7种写法

前言 单例模式是一种常用的软件设计模式,在他的核心结构中只包含一个被称为 单例的特殊类.通过单例模式可以保证系统只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案. Singletom类,定义一个GetInstance操作,允许客户访问他的唯一实例,GetInstance是一个静态方法,主要负责创建自己的唯一实例. 一.实现 1.饿汉式 public class Singleton { private s

Java设计模式系列之单例模式

单例模式的定义 一个类有且仅有一个实例,并且自行实例化向整个系统提供.比如,多程序读取一个配置文件时,建议配置文件时,建议配置文件封装成对象.会方便操作其中的数据,又要保证多个程序读到的是同一个配置文件对象,就需要该配置文件对象在内存中是唯一的. 单例模式的作用 简单说来,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个(当然也可以不存在). 单例模式的类图 如何保证对象的唯一性 思想:(1)不让其他程序创建该类对象; (2)在本类中创建一

[js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表

所谓组合模式,就是把一堆结构分解出来,组成在一起,现实中很多这样的例子,如: 1.肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的 2.组装的台式机同理,由主板,电源,内存条,显卡, 机箱,显示器,外设等组成的 把一个成型的产品组成部件,分成一个个独立的部件,这种方式可以做出很多灵活的产品,这就是组合模式的优势 比如:家用台式机电脑,要求配置比较低, 这个时候只需要主板+电源+内存条+机箱+显示器+外设就可以了,不需要配置独立显卡 鸡腿堡+鸡翅+紫薯

设计模式总结篇系列:单例模式(SingleTon)

在Java设计模式中,单例模式相对来说算是比较简单的一种构建模式.适用的场景在于:对于定义的一个类,在整个应用程序执行期间只有唯一的一个实例对象.如Android中常见的Application对象. 通过单例模式,自行实例化并向这个系统提供这个单一实例的访问方法. 根据此单一实例产生的时机不同(当然,都是指第一次,也是唯一一次产生此单一实例时),可以将其分为懒汉式.饿汉式和登记式. 一.懒汉式: 其特点是延迟加载,即当需要用到此单一实例的时候,才去初始化此单一实例.常见经典的写法如下: 1 pa

Java 设计模式系列(五)单例模式

Java 设计模式系列(五)单例模式 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 一.懒汉式单例 /** * 懒汉式单例类.在第一次调用的时候实例化自己 * 1. 构造器私有化,避免外面直接创建对象 * 2. 声明一个私有的静态变量 * 3. 创建一个对外的公共静态方法访问该变量,如果没有变量就创建对象 */ public class Singleton { private Singleton() throws InterruptedException { Thre

深入浅出设计模式系列 -- 单例模式

注:本文出自博主:chloneda 前言 深入浅出设计模式系列,尽量采用通俗易懂.循序渐进的方式,让大家真正理解设计模式的精髓! 单例模式知识点 在开始讲解单例模式之前,先了解一下单例模式的知识点. 单例模式定义:确保一个类只有一个自行实例化的实例,并提供一个全局访问点,向整个系统提供这个实例. 模式类型:创建类模式 单例模式类图: 单例模式可以简单总结为三个要素: 私有的构造方法. 提供私有的.静态的.指向当前实例的引用. 提供公有的.静态的方法 即全局访问点以返回这个实例. 单例模式的本质:

【白话设计模式四】单例模式(Singleton)

转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factory) [白话设计模式二]外观模式(Facade) [白话设计模式三]适配器模式(Adapter) [白话设计模式四]单例模式(Singleton) [白话设计模式五]工厂方法模式(Factory Method) [白话设计模式六]抽象工厂模式(Abstract Factory) [白话设计模式七]策