博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式 单例设计模式
阅读量:6497 次
发布时间:2019-06-24

本文共 3732 字,大约阅读时间需要 12 分钟。

hot3.png

基本定义

通过上面简单介绍,我们可以对单例模式有一个简单的认识。所谓单例模式就是确保某一个类只有一个实例,并且提供一个全局访问点。

从上面可以看出单例模式有如下几个特点:

  • 一、它只有一个实例。

  • 二、它必须要自行实例化。

  • 三、它必须自行想整个系统提供访问点。

 

模式结构

单例模式可以说是最简单的设计模式了,它仅有一个角色Singleton。

  • Singleton:单例。

 

模式实现

在看Spring单例应用之前,让我们来看一个Java的单例例子:

枚举方法实现单例

public class SingletonTest { @Test public void test() {   President president1 = (President) SingletonsHolder.PRESIDENT.getHoldedObject();   President president2 = (President) SingletonsHolder.PRESIDENT.getHoldedObject();   assertTrue("Both references of President should point to the same object", president1 == president2);   System.out.println("president1 = "+president1+" and president2 = "+president2);   // sample output   // president1 = com.waitingforcode.test.President@17414c8 and president2 = com.waitingforcode.test.President@17414c8 }}enum SingletonsHolder { PRESIDENT(new President()); private Object holdedObject; private SingletonsHolder(Object o) {         this.holdedObject = o; } public Object getHoldedObject() {         return this.holdedObject; }}class President {}

 

也可以用静态类内部加载的方式来实现单例

public class SingletonDemo {    private static class SingletonHolder{        private static SingletonDemo instance=new SingletonDemo();    }    private SingletonDemo(){        System.out.println("Singleton has loaded");    }    public static SingletonDemo getInstance(){        return SingletonHolder.instance;    }}

 

在Spring中,我们可以在bean工厂中找到单例应用的影子(例如在org.springframework.beans.factory.config.AbstractFactoryBean中):

/*** Expose the singleton instance or create a new prototype instance.* @see #createInstance()* @see #getEarlySingletonInterfaces()*/@Overridepublic final T getObject() throws Exception { if (isSingleton()) {   return (this.initialized ? this.singletonInstance : getEarlySingletonInstance()); } else {   return createInstance(); }}

 

我们看到,当需求对象被视为单例时,它只被初始化一次,并且在每次使用同一个bean类的实例后返回。我们可以在给定的例子中看到,类似于我们以前看到的President情况。将测试bean定义为:

 

测试用例如下所示:

public class SingletonSpringTest { @Test public void test() {   // retreive two different contexts   ApplicationContext firstContext = new FileSystemXmlApplicationContext("applicationContext-test.xml");   ApplicationContext secondContext = new FileSystemXmlApplicationContext("applicationContext-test.xml");   // prove that both contexts are loaded by the same class loader   assertTrue("Class loaders for both contexts should be the same",     firstContext.getClassLoader() == secondContext.getClassLoader());   // compare the objects from different contexts   ShoppingCart firstShoppingCart = (ShoppingCart) firstContext.getBean("shoppingCart");   ShoppingCart secondShoppingCart = (ShoppingCart) secondContext.getBean("shoppingCart");   assertFalse("ShoppingCart instances got from different application context shouldn't be the same",     firstShoppingCart == secondShoppingCart);   // compare the objects from the same context   ShoppingCart firstShoppingCartBis = (ShoppingCart) firstContext.getBean("shoppingCart");   assertTrue("ShoppingCart instances got from the same application context should be the same",     firstShoppingCart == firstShoppingCartBis); }}

 

这个测试案例显示了Spring单例模式与纯粹的单例设计模式的主要区别。尽管使用相同的类加载器来加载两个应用程序上下文,但是ShoppingCart的实例是不一样的。但是,当我们比较两次创建并属于相同上下文的实例时,我们认为它们是相等的。

也正因为有了单例,Spring可以控制在每个应用程序上下文中只有一个这样指定的bean的实例可用。因为适配器,Spring可以决定使用由谁来处理 JBossservlet容器中的加载时编织,也可以实现 ConfigurableListableBeanFactory的相应实例。第三种设计模式,装饰器,用于向Cache对象添加同步功能,还有Springboot的容器初始化。

 

模式优缺点

优点

  • 一、节约了系统资源。由于系统中只存在一个实例对象,对与一些需要频繁创建和销毁对象的系统而言,单

例模式无疑节约了系统资源和提高了系统的性能。

  • 二、因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。

缺点

  • 一、由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。

  • 二、单例类的职责过重,在一定程度上违背了“单一职责原则”。

模式使用场景

下列几种情况可以使用单例模式。

  • 一、系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器,或者需要考虑资源消耗太大而只允许创建一个对象。

  • 二、客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。

转载于:https://my.oschina.net/garlicts/blog/2243705

你可能感兴趣的文章
UIScrollView中的手势
查看>>
递归和迭代的差别
查看>>
基于jquery的可拖动div
查看>>
可以简易设置文字内边距的EdgeInsetsLabel
查看>>
[詹兴致矩阵论习题参考解答]习题1.3
查看>>
Android Fragment的使用
查看>>
mysql半同步复制实现
查看>>
沙朗javascript总结一下(一)---基础知识
查看>>
js深入研究之函数内的函数
查看>>
LeetCode:4_Median of Two Sorted Arrays | 求两个排序数组的中位数 | Hard
查看>>
uva-12657 - Boxes in a Line(双向链表)
查看>>
python之commands模块
查看>>
android应用开发--------------看RadioGroup源代码,写相似单选选项卡的集成控件(如底部导航,tab等等)...
查看>>
LeetCode - Binary Tree Level Order Traversal
查看>>
FTP协议完全详解
查看>>
iOS:实现图片的无限轮播
查看>>
【C语言天天练(十五)】字符串输入函数fgets、gets和scanf
查看>>
【环境配置】配置sdk
查看>>
accept()
查看>>
USB 2.0 Hub IP Core
查看>>