1、单例模式
概念:保证在内存中只用一个实例
使用场景:如 系统配置文件的管理,这些配置文件只要使用一个单例对象进行读写即可,系统总其他地方需要使用配置信息时,只要使用该单例对象进行获取就可以了,这样便于统一管理配置信息。
优缺点:
优点:在内存中只有一个对象,节省内存空间;
避免频繁的创建销毁对象,可以提高性能;
避免对共享资源的多重占用,简化访问;
为整个系统提供一个全局访问点。
缺点:不适用于变化频繁的对象;
滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;
示例:
1、饥饿模式(这种直线方式简单,且是线程安全的。)/** * 单例模式,饥饿加载 */ public class SingletonDemo { //1. 需要有一个私有的构造函数,防止该类通过new的方式创建实例 private SingletonDemo(){} //2. 饥饿模式,首先生成一个实例 private static final SingletonDemo instance = new SingletonDemo(); //3. 静态方法,用于获取已经生成的实例 public static SingletonDemo getInstance() { return instance; } public String hello(String name) { return "hello " + name; } }
2、懒汉模式第一种写法:(注意: 这种方式在多线程访问时会有问题)
/** * 单例模式: 懒汉式 */ public class SingletonDemo02 { private SingletonDemo02(){} private static SingletonDemo02 singletonDemo02 = null; public static SingletonDemo02 getInstance() { if (singletonDemo02 == null) { singletonDemo02 = new SingletonDemo02(); } return singletonDemo02; } public String hello(String name) { return "hello " + name; } }
第二种写法:/** * 单例模式: 懒汉式,线程安全,但性能较低 */ public class SingletonDemo03 { private SingletonDemo03() { } private static SingletonDemo03 singletonDemo03 = null; public static synchronized SingletonDemo03 getInstance(){ if(singletonDemo03 == null) { singletonDemo03 = new SingletonDemo03(); } return singletonDemo03; } public String hello(String name) { return "hello " + name; } }
第三种写法:(该方式依然会有线程安全问题)public class SingletonDemo03 { private SingletonDemo03() { } private static SingletonDemo03 singletonDemo03 = null; public static SingletonDemo03 getInstance(){ //系统减小同步块来提升性能,可以吗? if(singletonDemo03 == null) { synchronized (SingletonDemo03.class) { singletonDemo03 = new SingletonDemo03(); } } return singletonDemo03; } public String hello(String name) { return "hello " + name; } }
第四种写法:/** * 单例模式: 懒汉式,双重检查单例 */ public class SingletonDemo03 { private SingletonDemo03(){ } private static SingletonDemo03 singletonDemo03 = null; public static SingletonDemo03 getInstance(){ //减小同步块,并使用双重检查来保证线程安装,可以吗? if(singletonDemo03 == null) { synchronized (SingletonDemo03.class) { if(singletonDemo03 == null) { singletonDemo03 = new SingletonDemo03(); } } } return singletonDemo03; } public String hello(String name) { return "hello " + name; } }
第五种写法:/** * 单例模式: 懒加载, 线程安全 */ public class SingletonDemo04 { //阻止外部实例化 private SingletonDemo04(){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } //使用静态内部类来使用一个SingletonDemo04对象 private static class SingletonDemoHolder { private final static SingletonDemo04 instance = new SingletonDemo04(); } public static SingletonDemo04 getInstance() { return SingletonDemoHolder.instance; } public String hello(String name) { return "hello " + name; } }
第六种写法:(可以保证单例,且线程安全)public enum SingletonDemo05 { INSTANCE; public String hello(String name) { return "hello " + name; } }
2、工厂模式
概念:用于产生对象的方法或者式类,称之为工厂。 上面所讲到的单例模式也可以看作为一个特殊的工厂。使用场景:我们可以通过工厂模式,来集中控制对象的创建过程,这样可以给设计带来更多的灵活性。比如:spring的IOC容器就是工厂模式的经典实现。
方法:用于生产指定系列的对象。已鸭子为例,鸭子有真的鸭子,橡皮鸭,电子玩具鸭等。如何能方便的创建出各种鸭子,并将创建过程控制起来,以便于以后的维护和扩展?
类图:
抽象工厂:用于生成指定产品族,一个产品族中包括多种产品。例如:
我们都比较熟悉的电脑制造相关行业,有HP,罗技,联想,戴尔,近几年华为,小米也进来了,每个生产商生产的电脑又包括鼠标,键盘,屏幕等等配件。此时我们需要使用工厂模式来进行管理不同的产品族,这时使用简单工厂(也有叫作工厂方法的)已经无法满足要求,此时可以使用抽象工厂。类图:
3、责任链模式
概念:责任链模式是一个对象的行为模式,很多对象之间形成一条链条,处理请求在这个链条上进行传递,直到责任链的上的某个对象决定处理请求(也可扩展为几个对象处理),这个过程对于用户来说是透明的,也就是说用户并不需要知道是责任链上的哪个对象处理的请求,对请求是否处理由链条上的对象自己决定。
为了便于理解我们可以想象一下击鼓传花的游戏。
使用场景:
web容器中的过滤器算是责任链模式的一个经典场景。另外举个例子:当在论坛上提交内容时,论坛系统需要对一些关键词进行处理,看看有没有包含一些敏感词汇,而这些敏感词汇我们可以使用责任链模式进行处理。
类图:
4、观察者模式
概念:观察者模式是对象的行为模式,有时也称为“发布/订阅模式”或者“监听器模式”。
观察者模式定义了观察者和被观察者之间的一点多的关系,让多个观察者对象可以响应一个被观察者对象。
使用场景:比较经典的使用场景,比如:java中的swing包中对事件的处理。浏览器对鼠标,键盘等事件的处理等, spring中的事件发布机制也是使用该模式。
类图: