今天分享一下单例模式的几种写法,以及抽象工厂的实现代码,希望能对你各位大佬有所帮助。
1. 为什么需要学习设计模式
设计模式(Design pattern)代表了最佳的实践,是很多优秀的软件开发人员的经验总结,是解决特定问题的解决方案。它并不是语法规定,也不拘泥于特定语言。 恰当的使用设计模式可以代码的可复用性,可维护性,可扩展性,健壮性及安全性,这些都是系统非常重要的非功能性需求。
2、常见的设计模式
2.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 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.2工厂模式
作用
使用工厂的原因是我们可以通过工厂模式,来集中控制对象的创建过程,这样可以给设计带来更多的灵活性;列spring的IOC容器就是工厂模式的经典实现
图解
用于生产指定系列的对象。已鸭子为例,鸭子有真的鸭子,橡皮鸭,电子玩具鸭等。如何能方便的创建出各种鸭子,并将创建过程控制起来,以便于以后的维护和扩展?
2.3抽象工厂
用于生成指定产品族,一个产品族中包括多种产品。例如: 我们都比较熟悉的电脑制造相关行业,有HP,罗技,联想,戴尔,近几年华为,小米也进来了,每个生产商生产的电脑又包括鼠标,键盘,屏幕等等配件。此时我们需要使用工厂模式来进行管理不同的产品族,这时使用简单工厂(也有叫作工厂方法的)已经无法满足要求,此时可以使用抽象工厂
代码
PcFactory工厂类
public abstract class PcFactory { public abstract Mouse makeMouse(); public abstract Keyboard makeKeyboard(); private static HpFactory hpFactory = new HpFactory(); private static LogicFactory logicFactory = new LogicFactory(); public final static int PC_TYPE_HP = 1; public final static int PC_TYPE_LG = 2; public static PcFactory getPcFactory(int pcType) { switch (pcType){ case 1: return hpFactory; case 2 : return logicFactory; default: return null; } }Mouse类
public abstract class Mouse { abstract String getInfo(); }Hpkeyboard类
public class HpKeyboard extends Keyboard { @Override String getInfo() { return "HP keyboard"; } }2.4责任链模式
作用
web容器中的过滤器算是责任链模式的一个经典场景。另外举个例子:当在论坛上提交内容时,论坛系统需要对一些关键词进行处理,看看有没有包含一些敏感词汇,而这些敏感词汇我们可以使用责任链模式进行处理。
2.5 观察者模式(Obsever)
作用
比较经典的使用场景,比如:java中的swing包中对事件的处理。浏览器对鼠标,键盘等事件的处理等, spring中的事件发布机制也是使用该模式。