我是架构师--设计模式-单例模式

简介:

来次面试吧?准备好没,GO!

 

  1.    问:自我介绍下吧。(开个玩笑。。。往下)请问你用过单例模式吗?什么是单例?  
  2. 答:用过啊,单例模式就是只创建一个实例。  
  3.    问:噢?那是单线程,还是多线程下都是呢?  
  4. 答:这个类在JVM里就一个实例(这样回答也许会更好)  
  5.    (注:通常面试官,到这里,就会让你写一个单例,当然我们不,你看这篇文章,就是不让你再网上找其他重复的资料了。)  
  6.    问:说说你用的场景吧  
  7. 答:........  
  8.    问:说说单例的几种类型?或者说何时对实例的初始化?  
  9. 答:........  
  10.    问:画过单例的类图吗?会画吗?  
  11. 答:(需要吗?)  
  12.    问:写个单例的实现吧?  

 类名:SingleTon

 实例:uniqueInstance 简称ust吧。(这里我插入一句编程规范:起名不要吝惜把实例代表的意思表达清楚,名字可稍微长点,这里就是想偷懒) 

实现1:


  
  
  1. public class Singleton{  
  2.   private final static Singleton ust = new Singleton();  
  3.   private Singleton() {}  
  4.   public static Singleton getInstance(){  
  5.      return ust;  
  6.   }  
  7. }  

注:这里顺便说明一下语法。通常final与static同时出现,习惯让final在前

分析: 

1. 这里需要加final吗? 是的,因为java反射,可以改变private描述的变量

2. 有书里把这种方式称为饿汉单例模式(另一个种叫懒汉单例),并且已经为人所接受

3. 在多线程方面表现出了他优势,不需要担心方法重复里延时创建带来的原子性(这样说难理解,其实就是出现两个或多个实例)

4. 这个,不符合我们习惯的 用到时再实例化的原则(不过这没关系。。。)

 看,其实你发现这还是个不错的单例,那么其实有个最好的实现,最好的实现:

单元素的枚举类型已经成为Singleton的最佳实践

即使面对复杂的序列化或者反射攻击,绝对防止多次实例化,还有他的简洁和优雅。

 ----好吧,面试结束了。 其实你对单例的理解还是不错的,而且你已经得到了最好的答案,有兴趣彻底玩转单例吗,继续听我唠叨。


    我们看看懒汉单例模式:

实现2:


  
  
  1. public class Singleton{  
  2.     // private final static Singleton ust = null;
  3. // 不该加final,这里明显有偷懒嫌疑,复制上面的例子,又测试不够,以后尽量避免类似问题。
  4. // 8月15日修正
  5. private static Singleton ust = null;
  6.      private Singleton(){}  
  7.      public staic Singleton getInstance(){  
  8. //建议null==ust的方式,能帮助更快的发现错误。
  9. //部分老程序员的习惯,其实许多IDE会发现些低级错误。  
  10.         if(ust==null){//A  
  11.              ust = new Singleton();//B  
  12.          }  
  13.        return ust;  
  14.      }  
  15. }   

分析:

1. 懒汉模式,做到了需要时创建实例

2. 他遇到了尴尬的问题,因为当两个线程分开运行到A,然后进入了if块,可能就创建了2个实例,草稿的是,你已经初始了一些数据。 

改进一下:

实现3: 


  
  
  1. public class Singleton{  
  2. private volatile static Singleton ust;  
  3. private Singleton(){}  
  4. public staic Singleton getInstance(){  
  5. synchronized(Singleton.class){  
  6.    if(ust==null){  
  7.     ustnew Singleton();  
  8.    }  
  9.  }  
  10. return ust;  
  11. }  
  12. }  

 分析:

  1. 如果你不理解synchronized 的位置,就不用单例模式这么多写法,不如学习基础

  2. volatile 确保ust被实例化后,多个线程正确处理。他失去了JVM必要的代码优化,如果不是多线程,就不要用

   3. 这个叫做 “双检查加锁”,单例最后一种方式


综合讨论会: 


  
  
  1. 小明: 单例目前一共谈到懒汉和饿汉两种,还有双检查加锁,最好的应该是单元素的枚举类型  
  2. 小刚: 是的,回答了开头说的几种单例,那么哪些场景应该用单例呢?  
  3. 小明: 我知道,有线程池,缓存,处理偏好设置,注册表,日志对象等等  
  4. 小刚: 对,我对java比较了解,我知道Runtime.getRuntime()。   
  5. C(为吗我叫C):我知道有java.lang.reflect.Proxy类   
  6. 小明:有什么共同点呢,为什么用?是遵循对象尽量少创建原则? 
  7. C:这是什么意思?   
  8. 小刚:这很简单,不过这说法有点问题。因为对象占内存,有要造成垃圾回收,GC的时候JVM可是只干这个麻烦事  
  9. 小明:是啊 
  10. 小刚:我想我知道,某些对象最好只有一个实例,多了会有问题产生。   
  11. C:什么问题?   
  12. 小刚:比如缓存,你从哪个实例里拿缓存呢?   
  13. 小明:是的啊。。。  

结束讨论会,总结一下吧。不,等等,还要补充两句: 
1. 单例模式定义:确保一个只有一个实例,并提供一个全局访问点

2. 如果getInstance()方法对应用程序不会额外负担,或者说影响不大,那写成怎样,其实没太大所谓。但是如果频繁运行,就要仔细考虑,因为一个同步,可能使得执行效率下降100倍

 

继续总结,还差个UML图呢,不妨在上个枚举的例子吧,枚举构造器默认私有吗? 

image 


枚举就算了,是不是默认构造器,自己研究下吧。。。呵呵

这回真总结了: 
1. 单例,有懒汉,饿汉,双检查加锁3种常见用法 
2. 单例模式,是因为如果多了,会造成数据遗漏等麻烦 
3. 最好的单例,单元素的枚举类型

 呵呵,其实,就这些,本来想先写工厂的,因为去面试,遇到某些对单例了解比较浅,解释起来费劲,于是先以单例开篇,请关注下篇工厂模式。










本文转自 wws5201985 51CTO博客,原文链接:http://blog.51cto.com/yjplxq/931861,如需转载请自行联系原作者
目录
相关文章
|
22天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
27 2
|
3天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
11天前
|
设计模式 存储 数据库连接
PHP中的设计模式:单例模式的深入理解与应用
【10月更文挑战第22天】 在软件开发中,设计模式是解决特定问题的通用解决方案。本文将通过通俗易懂的语言和实例,深入探讨PHP中单例模式的概念、实现方法及其在实际开发中的应用,帮助读者更好地理解和运用这一重要的设计模式。
10 1
|
15天前
|
设计模式 API 持续交付
深入理解微服务架构:设计模式与实践
【10月更文挑战第19天】介绍了微服务架构的核心概念、设计模式及最佳实践。文章详细探讨了微服务的独立性、轻量级通信和业务能力,并介绍了聚合器、链式和发布/订阅等设计模式。同时,文章还分享了实施微服务的最佳实践,如定义清晰的服务边界、使用API网关和服务发现机制,以及面临的挑战和职业心得。
|
22天前
|
设计模式 测试技术 持续交付
架构视角下的NHibernate:设计模式与企业级应用考量
【10月更文挑战第13天】随着软件开发向更复杂、更大规模的应用转变,数据访问层的设计变得尤为重要。NHibernate作为一个成熟的对象关系映射(ORM)框架,为企业级.NET应用程序提供了强大的支持。本文旨在为有一定经验的开发者提供一个全面的指南,介绍如何在架构层面有效地使用NHibernate,并结合领域驱动设计(DDD)原则来构建既强大又易于维护的数据层。
35 2
|
27天前
|
设计模式 存储 数据库连接
PHP中的设计模式:单例模式的深入解析与实践
在PHP开发中,设计模式是提高代码可维护性、扩展性和复用性的关键技术之一。本文将通过探讨单例模式,一种最常用的设计模式,来揭示其在PHP中的应用及优势。单例模式确保一个类仅有一个实例,并提供一个全局访问点。通过实际案例,我们将展示如何在PHP项目中有效实现单例模式,以及如何利用这一模式优化资源配置和管理。无论是PHP初学者还是经验丰富的开发者,都能从本文中获得有价值的见解和技巧,进而提升自己的编程实践。
|
24天前
|
设计模式 安全 Java
C# 一分钟浅谈:设计模式之单例模式
【10月更文挑战第9天】单例模式是软件开发中最常用的设计模式之一,旨在确保一个类只有一个实例,并提供一个全局访问点。本文介绍了单例模式的基本概念、实现方式(包括饿汉式、懒汉式和使用 `Lazy<T>` 的方法)、常见问题(如多线程和序列化问题)及其解决方案,并通过代码示例详细说明了这些内容。希望本文能帮助你在实际开发中更好地应用单例模式,提高代码质量和可维护性。
29 1
|
28天前
|
设计模式 缓存 数据库连接
探索PHP中的设计模式:单例模式的实现与应用
在PHP开发中,设计模式是提高代码可复用性、可维护性和扩展性的重要工具。本文将深入探讨单例模式(Singleton Pattern)的基本概念、在PHP中的实现方式以及实际应用场景。单例模式确保一个类仅有一个实例,并提供全局访问点。通过具体代码示例和详细解释,我们将展示如何在PHP项目中有效利用单例模式来解决实际问题,提升开发效率和应用性能。
|
1月前
|
设计模式 存储 测试技术
PHP中的设计模式:单例模式的深入解析与实践
在PHP开发领域,设计模式是解决常见问题的最佳实践。本文将深入探讨单例模式,一种确保类只有一个实例的设计模式,并提供实际应用示例。我们将从单例模式的基本概念讲起,通过实际案例展示如何在PHP中实现单例模式,以及它在不同场景下的应用和优势。最后,我们会探讨单例模式的优缺点,帮助开发者在实际项目中做出明智的选择。
|
1月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP开发领域,设计模式是解决常见问题的高效方案集合。它们不是具体的代码,而是一种编码和设计经验的总结。单例模式作为设计模式中的一种,确保了一个类仅有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的基本概念、实现方式及其在PHP中的应用。
单例模式在PHP中的应用广泛,尤其在处理数据库连接、日志记录等场景时,能显著提高资源利用率和执行效率。本文从单例模式的定义出发,详细解释了其在PHP中的不同实现方法,并探讨了使用单例模式的优势与注意事项。通过对示例代码的分析,读者将能够理解如何在PHP项目中有效应用单例模式。