前言

在刚学编程没多久就听说过设计模式的大名,不过由于当时还是个彻彻底底的菜鸟,并没有去触碰。直到在开始工作中对简单的业务代码较为熟悉之后,才正式的接触设计模式。当时最早接触的设计模式是工厂模式,不过本文讲的是单例模式,这里就留着下篇文章中在讲解。至于为什么先讲解单例模式? 那是因为单例模式是设计模式中最简单的... 。凡事总有个先后顺序,所以就先易后难了。好了,废话不多说了,开始进入正片。

设计模式简介

说明:这里说了的简介就是真的 “简介”。

什么是设计模式

设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。

为什么使用设计模式

使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。

设计模式类型

设计模式有23种类型。按照主要分类可以分为三大类:

一、创建型模式

这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

  • 单例模式
  • 工厂模式
  • 抽象工厂模式
  • 建造者模式
  • 原型模式

二、结构型模式

这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。

  • 适配器模式
  • 桥接模式
  • 过滤器模式
  • 组合模式
  • 装饰器模式
  • 外观模式
  • 享元模式
  • 代理模式

三、行为型模式

这些设计模式特别关注对象之间的通信。

  • 责任链模式
  • 命令模式
  • 解释器模式
  • 迭代器模式
  • 中介者模式
  • 备忘录模式
  • 观察者模式
  • 状态模式
  • 空对象模式
  • 策略模式
  • 模板模式
  • 访问者模式

设计模式的原则

设计模式的六大原则

  1. 开闭原则:对扩展开放,对修改关闭。
  2. 里氏代换原则:对开闭原则的补充。任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。
  3. 依赖倒转原则:针对接口编程,依赖于抽象而不依赖于具体。
  4. 接口隔离原则:尽量使用多个隔离的接口,为了降低类之间的耦合度。
  5. 迪米特法则:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。
  6. 合成复用原则:尽量使用合成/聚合的方式,而不是使用继承。

单例模式

什么是单例模式

保证一个系统中的某个类只有一个实例而且该实例易于外界访问。例如Windows界面的任务管理器就可以看做是一个单例。

单例模式的使用场景

在程序中比较常用的是数据库连接池线程池日志对象等等。

单例模式使用

最早我们在学习单例模式的时候,基本都会接触这两种模式:饿汉式和饱汉式(懒汉式)。
那我们先来看看这两个模式的实现。

饿汉式
定义一个私有的构造方法,并将自身的实例对象设置为一个私有属性,并加上static和final修饰符,然后通过公共的静态方法调用返回实例。

 class SingletonTest1 {  private SingletonTest1() {  }  private static final SingletonTest1 instance = new SingletonTest1();  public static SingletonTest1 getInstance() {  return instance;  }
}

饱汉式
定义一个私有的构造方法,定义一个该类静态私有的变量,然后定义一个公共的静态方法,对该类的值进行空判断,不为空直接返回,否则重新构建一个。

class SingletonTest2 {private SingletonTest2() {   }   private static SingletonTest2 instance;   public static SingletonTest2 getInstance() {   if (instance == null) {instance = new SingletonTest2();}   return instance;   }   }  

简单的介绍了这两种的模式,然后我们再来看看这两种模式的优缺点吧。
饿汉式

  • 优点:写起来很简单,并且不会因为不加synchronized关键字而造成的线程不安全问题。
  • 缺点:当该类被加载的时候,会初始化该实例和静态变量并被创建并分配内存空间,并且会一直占用内存。

饱汉式

  • 优点:写起来很简单,在第一次调用的时候才会初始化,节省了内存。
  • 缺点:线程不安全,多个线程调用可能会出现多个实例。
  • 总结:书写简单,线程不安全,效率还行。

虽然 饱汉式可以通过加上synchronized关键字保证线程安全。但是效率方法来说还不说是最优。

这里在介绍下个人认为在JDK1.5之前最优的两种写法,一种是静态内部类,另一种是双重锁检查

静态内部类
定义一个私有的构造方法,定义一个该类私有静态的内部类,然后在内部类中定义一个该类的静态变量,然后通过公共的final修饰的静态方法调用返回实例。

  class  SingletonTest4 {private SingletonTest4(){}private static class SingletonTest5{private static SingletonTest4 instance = new SingletonTest4();}public static final SingletonTest4 getInstance(){return SingletonTest5.instance;}}

因为该类的内部类是私有的,除了对外公布的公共静态方法getInstance(),是无法访问的。因为它是延迟加载,所以读取读取实例的时候不会进行同步,几乎没有性能的缺陷,而且还是线程安全的,并且不依赖JDK的版本。

双重锁检查
定义一个私有构造方法,通过volatile定义静态私有变量,保证了该变量的可见性,然后定义一个共有的静态方法,第一次对该对象实例化时与否判断,不为空直接返回,提升效率;然后使用synchronized 进行同步代码块,防止对象未初始化时,在多线程访问该对象在第一次创建后,再次重复的被创建;然后第二次对该对象实例化时与否判断,如果未初始化,则初始化,否则直接返回该实例。

  class SingletonTest6 { private SingletonTest6() { }   private static volatile SingletonTest6 instance;  public static SingletonTest6 getIstance() { if (instance == null) {synchronized (SingletonTest6.class) {if (instance == null) {instance = new SingletonTest6();   }   }   }   return instance;   }   }  

这种模式在很长的一段时间内可以说是最优的了,内存占用低,效率高,线程安全,多线程操作原子性。但是有个缺点就是书写麻烦,对新手不太友好。

JDK1.5之后出现了枚举,并且完美支持单例模式,并且线程安全、效率高!但是这些不是最重要的,最重要的是书写超级简单!究竟有多简单,看下面的示例应该就可以了解一下了。。。

枚举单例

 enum SingletonTest7{INSTANCE;}

对的,你没看错,就这点代码,其它不需要了。。。
枚举需要在JDK1.5之后的版本,它无偿提供序列化机制,绝对防止多次实例化,即使在面对复杂的序列化或者反射攻击的时候。这种方法也被Effective Java作者Josh Bloch 所提倡。

总结

单例模式的几种使用就到这了,那么我们来总结下使用单例模式需要注意什么(不包括枚举)。

  1. 构造方法私有化(private);
  2. 定义一个私有(private)静态(static)实例化对象;
  3. 对外提供一个公共(public)静态(static)的方法得到该实例;

原创不易,如果感觉不错,希望给个推荐!您的支持是我写作的最大动力!
版权声明:
作者:虚无境
博客园出处:http://www.cnblogs.com/xuwujing
CSDN出处:http://blog.csdn.net/qazwsxpcm    
个人博客出处:http://www.panchengming.com

转载于:https://www.cnblogs.com/xuwujing/p/9277266.html

Java进阶篇设计模式之一 ----- 单例模式相关推荐

  1. Java进阶篇设计模式之十三——观察者模式和空对象模式

    简介 观察者模式又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式.源-监听器(Source/Listener)模式或从属者(Dependents)模式. ...

  2. Java进阶篇设计模式之十三 ---- 观察者模式和空对象模式

    前言 在上一篇中我们学习了行为型模式的备忘录模式(Memento Pattern)和状态模式(Memento Pattern).本篇则来学习下行为型模式的最后两个模式,观察者模式(Observer P ...

  3. Java进阶篇设计模式之九----- 解释器模式和迭代器模式

    前言 在上一篇中我们学习了行为型模式的责任链模式(Chain of Responsibility Pattern)和命令模式(Command Pattern).本篇则来学习下行为型模式的两个模式, 解 ...

  4. Java进阶篇设计模式之十一 ---- 策略模式和模板方法模式

    前言 在上一篇中我们学习了行为型模式的访问者模式(Visitor Pattern)和中介者模式(Mediator Pattern).本篇则来学习下行为型模式的两个模式,策略模式(Strategy Pa ...

  5. Java进阶篇设计模式之十二 ---- 备忘录模式和状态模式

    前言 在上一篇中我们学习了行为型模式的策略模式(Strategy Pattern)和模板模式(Template Pattern).本篇则来学习下行为型模式的两个模式,备忘录模式(Memento Pat ...

  6. Java进阶之设计模式正则表达式

    Java进阶之设计模式&正则表达式 一.设计模式 1.1 设计模式概述 1.2 单例模式 1.2.1 单例模式衍生--多例模式 1.2.2 单例模式衍生--枚举 1.3 工厂模式 二.正则表达 ...

  7. java 23种设计模式 04 单例模式

    java 23种设计模式 04 单例模式 一.什么是单例模式 单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象.也就是说,在整个程序空间中,该类只存在一个实例对象.   ...

  8. Java基础篇--设计模式

    目录 前言 设计模式 创建型模式 单例模式 工厂方法模式 抽象工厂模式 建造者模式 原型模式 结构型模式 适配器模式 桥接模式 组合模式 装饰模式 外观模式 亨元模式 代理模式 行为型模式: 访问者模 ...

  9. Java进阶篇(一)——接口、继承与多态

    前几篇是Java的入门篇,主要是了解一下Java语言的相关知识,从本篇开始是Java的进阶篇,这部分内容可以帮助大家用Java开发一些小型应用程序,或者一些小游戏等等. 本篇的主题是接口.继承与多态, ...

最新文章

  1. linux使用世界时间,linux世界里的时间
  2. Spring整合CXF,发布RSETful 风格WebService
  3. 第十五届全国大学生智能车竞赛百度深度学习车模
  4. 球迷必备Euro Cup Mobile 2008 !-dopod touch diamond试用之欧洲杯
  5. “约见”面试官系列之常见面试题第二十二篇之函数闭包(建议收藏)
  6. 谈Servlet与JSP
  7. 【BZOJ2084】【洛谷P3501】[POI2010]ANT-Antisymmetry(Manache算法)
  8. mysql 时间点_mysql 时间
  9. java蓝牙开发_Android蓝牙开发全面总结
  10. 神经网络过拟合解决方法,神经网络过拟合现象
  11. c#写图像tif gdal_C#使用GDAL将tif图像转换为jpg、bmp、png和gif格式的图像
  12. cdr软件百度百科_Cdr是什么软件
  13. 不同公式等号对齐_特级老师整理:二年级数学公式、法则、儿歌、口诀
  14. Java基础8顺序语句判断语句
  15. 爬虫那些事-网页爬虫设计思路
  16. SAP系统Sizing的原理
  17. 2022最新二开微交易系统股票配资理财系统源码+附教程
  18. 特征重要性与shap值
  19. 求c语言学习的教程网站
  20. PDN电源完整性设计

热门文章

  1. Linux系统日志详解
  2. php中三元运算符用法
  3. springmvc返回值、数据写到页面、表单提交、ajax、重定向
  4. ebook site
  5. Blueprint:一个让你获取示例代码的Flash Builder扩展
  6. Linux shell命令提示符
  7. Android编程之SparseArrayE详解 Android编程之SparseArrayE详解
  8. Android开发学习之以CameraAPI方式实现相机功能(二)——相机功能配置
  9. 10 个最佳的支持触摸操作的 JavaScript 框架
  10. Android应用开发——系统自带样式Android:theme