软件设计模式(DesignPattern)
Java中一般常用的设计模式有23种,其中常用的几种设计模式应该去掌握。 总体来说设计模式分为三大类:
创建型模式,共5种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共7种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
单例模式
1、什么是单例模式?
百度百科是这样定义的:单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例
我是这样理解的:单例模式就是只允许一个实例,最开始使用它的时候是C#中,我要实例化一个A窗体,但是有个需求就是A窗体必须是唯一,不管我在B窗体操作A窗体还是C窗体中操作A窗体都是如此,这时候就使用到了单例模式。
2、单例模式分类
-
懒汉单例模式:在第一次调用的时候实例化本身,在并发环境下,可能出现多个本身对象。所以线程是不安全的。
-
饿汉单例模式:在类初始化时,已经自行实例化一个静态对象,所以本身就是线程安全的。
-
登记单例模式:通过一个专门的类对各单例模式的单一实例进行管理和维护。
-
枚举模式
3、特点
A、 单例模式类只能有一个实例 B、 单例模式类必须自己创建自己的唯一实例 C、 单例模式类必须给所有其他对象提供这一实例
代码示例
1:懒汉模式example
public class SingleExample {
/**
* 该函数限制用户主动创建实例
*/
private SingleExample() {}
private static SingleExample singleExample= null;
/**
* 获取SingleExample实例(也叫静态工厂方法)
* @return SingleExample
*/
public static SingleExample getSingleExample() {
/* SingleExample为空时创建它,反之直接返回,保证唯一性 */
if(singleExample == null){
singleExample = new SingleExample();
}
return singleExample;
}
}
这种方式在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快。 这种方式基于类加载机制避免了多线程的同步问题,但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到懒加载的效果。
2:饿汉模式example
public class SingleExample {
/**
* 该函数限制用户主动创建实例
*/
private SingleExample() {}
private static final SingleExample singleExample = new Singleton();
/**
* 获取SingleExample实例,也叫静态工厂方法
* @return SingleExample
*/
public static SingleExample getInstance() {
return SingleExample;
}
}
3:静态内部类单例模式
public class SingleExample {
/**
* 类级的内部类,也就是静态类的成员式内部类,该内部类的实例与外部类的实例
* 没有绑定关系,而且只有被调用时才会装载,从而实现了延迟加载
* @author dream
*
*/
private static class SingleExampleHolder{
/**
* 静态初始化器,由JVM来保证线程安全
*/
private static final SingleExample instance = new SingleExample();
}
/**
* 私有化构造方法
*/
private SingleExample(){
}
public static SingleExample getInstance(){
return SingleExampleHolder.instance;
}
}
4:登记模式example
public class SingleExample {
// 存储需要进行维护和管理的类的实例
private static Map<String, SingleExample> map = new HashMap<String, SingleExample>();
/**
* 静态创建实例并添加到Map集合
*/
static {
SingleExample singleExample = new SingleExample();
map.put(SingleExample.getClass().getName(), singleExample);//运用了反射
}
/**
* 该函数限制用户主动创建实例
*/
private SingleExample() {};
/**
* 静态工厂方法,返回指定登记对象的唯一实例
* 对于已经登记的直接取出返回,对于还未登记的先登记,然后取出返回
*
*/
public static RegMap getInstance(String name){
if(name==null){
name="SingleExample";
}
if(map.get(name)==null){
try {
map.put(name, (RegSingleton) Class.forName(name).newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
return map.get(name);
}
}
5:枚举单例模式
public enum SingleExample {
INSTANCE;
public void doSomeThing() {
}
}
枚举单例的优点就是简单,但是大部分应用开发很少用枚举,可读性并不是很高,不建议使用。