JavaSE必备知识点7-设计模式

设计模式GOF23 –group of four

设计模式分类

这些设计模式的套路是基本上固定的,要把握这些设计模式的使用场景,这个模式的意义,更多的是一种思考和思维模式的转化,而不是要背一些代码,下面是23种设计模式。

创建型模式:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。

结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。

行为型模式:模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。

单例模式★

核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。

常见应用场景

  • Windows的任务管理器
  • Windows的回收站
  • 项目中,读取配置文件的类,一般也只有一个对象。
  • 网站的计数器
  • 应用程序的日志应用,一般都采用单例模式,这一般是由于共享的日志文件一直处于打开状态,只能由一个实例去操作,否则内容不好追加。
  • 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。
  • 操作系统的文件系统:一个操作系统只用有一个文件系统。
  • Application也是单例的典型应用。
  • 在Spring中,每个Bean默认就是单例的,这样做的优点是Spring容器可以管理。
  • 在servet编程中,每个Servlet也是单例
  • 在spring MVC框架/struts1框架中,控制器对象也是单例。

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

单例模式可以在系统设置全局的访问点,优化环共享资源访问。

常用的五种单例模式实现方式

  • 饿汉式★:线程安全,调用效率高,不可延时加载。
  • 懒汉式★:线程安全,调用效率不高,可以延时加载。
  • 双重检测锁式:由于JVM底层内部模型原因,偶尔会出问题,不建议使用。
  • 静态内部类式:线程安全,调用效率高,可以延时加载。
  • 枚举单例:线程安全,调用效率高,不可以延时加载。

饿汉式实现★

饿汉式单例模式代码中,static变量会在类加载时初始化,此时也不会涉及多个线程对象访问该对象的问题。虚拟机保证只会装载一次该类,肯定不会发生并发访问的问题,因此,可以省略synchronized关键字。

加载类的时候,线程天然是安全的,因此,此状态下,线程一定安全。

1
2
3
4
5
6
7
8
9
10
11
//测试饿汉式单例模式  
public class SingletonDemo{
//实例对象私有化 类初始化时,立即加载这个对象,即不能够延时加载。
private static /*final*/ SingletonDemo s = new SingletonDemo();
//构造器私有化
private SingletonDemo(){}
//访问该实例的全局访问点 该类中不可创建对象,只能得到这个对象
public static /*synchronized*/ SingletonDemo getInstance(){
return s;
}
}

从上面的代码可以看出,实例对象在类加载的时候就创建好了,无论该对象是否使用,都已经花费了创建这个类的时间,没有延时加载的优势

懒汉式实现★

懒汉式就区别于上面的饿汉式上来就加载对象,它现在是延时加载,也就是等有用的时候再加载,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class SingletonDemo2{
//不初始化 延时加载 真正用的时候再加载
private static SingletonDemo2 s;
//构造器私有化
private SingletonDemo2(){}
//需要同步 并发效率较低 避免在并发量高的情况下创建多个对象
public static synchronized SingletonDemo2 getInstance(){
if(s==null){
s = new SingletonDemo2();
}
return s;
}
}

从上面的代码来看,相比于饿汉式做到了延时加载,即等到用该对象的时候再进行加载,资源利用率高了。但是,每次调用getInstance()都需要同步,也就降低了并发效率。

双重检测锁式实现

静态内部类式

枚举单例

您的每一份支持将鼓励我继续创作!
-------------本文结束感谢您的阅读-------------