设计模式-(概述+单例模式)

一.概述
1.创建型模式 :
—–单例模式,抽象工厂模式,建造者模式,原型模式。

2.结构型模式:
—–适配器模式,桥接模式,装饰模式,组合模式,外观模式,享元模式,代理模式。

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

单例模式 :
保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。
例子(常见的应用场景) :
windows 的Task Manager(任务管理器) ,Recycle Bin(回收站)就是很典型的单例模式 网站的计数器,操作系统的文件系统,Spring MVC框架/struct1框架中,控制器对象也是单例。

单例模式的优点:
-由于单例模式只生成一个实例,减少了系统性能的开销,当一个对象的产生需要比较多的资源时,如读取配置,产生其他依赖对象时,则可以通过在应运启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。
-单例模式可以在系统设置全局的访问点,优化环共享资源访问,例如设计一个单例类,负责所有数据表的映射处理。

五种常见的单例模式的实现方法:
——主要
饿汉式(线程安全,调用效率高。但是,不能延时加载。)

1
2
3
4
5
6
7
8
9
10
11
12
//测试饿汉单例模式
public class SingletonDemo1 {

//2.之后提供静态属性,类初始化时立即加载这个对象(没有延时加载的优势)。加载类时,天然的是线程是安全的
private SingletonDemo1() { //饿汉式 1.首先要私有构造器
}

//方法没有同步,调用的效率高
public static SingletonDemo1 getInstance() {
return instance;
}
}

懒汉式(线程安全,调用效率不高,但是,可以延时加载)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//测试懒汉式单例模式

public class SingletonDemo2 {
//2.类初始化时,不初始化这个对象(延时加载,真正用的时候再创建)
private static SingletonDemo2 instance;

private SingletonDemo2() { //饿汉式 1.首先要私有构造器

}
//方法同步,调用的效率低
public static synchronized SingletonDemo2 getInstance() {
if(instance == null) {
instance = new SingletonDemo2();
}
return instance;
}

}

——其他:
双重检测锁式(由于JVM底层内部模型的原因,偶尔会出现问题。不建议使用)

静态内部类式(线程安全,调用效率高,但是,可以延时加载) 枚举单例(线程安全,调用效率高,不能延时加载)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*测试静态内部类实现单例模式
* 优点:线程安全,调用效率高,并且实现了延时加载
*/

public class SingletonDemo04 {

private static class SingletonClassInstance{
private static final SingletonDemo04 instance = new SingletonDemo04();
}

public static SingletonDemo04 getInstance() {
return SingletonClassInstance.instance;
}

private SingletonDemo04() {

}
}

枚举类型实现单例模式
(优点:
-操作简单
-枚举本身就是单例模式,由JVM从根本上提供保障!避免通过反射和反序列化的漏洞
缺点:无延时加载)

1
2
3
4
5
6
7
8
9
10
11
//测试枚举式实现单例模式(没有懒加载效果)
public enum SingletonDemo5 {

//这个枚举元素,本身就是单例对象
INSTANCE;

//添加自己需要的操作
public void singletonOPeration() {

}
}

测试效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Client {
public static void main(String[] args) {
SingletonDemo1 s1 = SingletonDemo1.getInstance();
SingletonDemo1 s2 = SingletonDemo1.getInstance();
System.out.println(s1);
System.out.println(s2);

SingletonDemo2 s3 = SingletonDemo2.getInstance();
SingletonDemo2 s4 = SingletonDemo2.getInstance();
System.out.println(s3);
System.out.println(s4);

SingletonDemo04 s5 = SingletonDemo04.getInstance();
SingletonDemo04 s6 = SingletonDemo04.getInstance();
System.out.println(s5);
System.out.println(s6);

System.out.println(SingletonDemo5.INSTANCE==SingletonDemo5.INSTANCE);
}

}

如何选用呢?
——单例对象 占用 资源 少,不需要 延时加载:

  • 枚举式 好于 饿汉式

——单例对象 占用 资源 多,需要 延时加载:

  • 静态内部类 好于 懒汉式