设计模式之单例、工厂
单例模式:确保某一个类在系统中只有一个实例,并自行实例化,同时向外部提供获取这个唯一实例的接口
饿汉式:
class EagerSingleton { // 静态变量,类在创建之初就会执行实例化动作。 private static EagerSingleton instance = new EagerSingleton(); // 私有化构造函数,使外界无法创建实例 private EagerSingleton(){} // 为外界提供获取实例接口 public static EagerSingleton getInstance(){ return instance; } }
缺点:这种空间换时间的方式,即使类实例本身还未用到,实例也会被创建。
懒汉式:
class Singleton2 { //volatile 原子性操作 private volatile static Singleton2 instance = null; /** * 设置标志位 * */ private static boolean youyuan = false; private Singleton2(){ synchronized (Singleton2.class){ if (youyuan == false){ youyuan = true; }else { throw new RuntimeException("不要试图使用反射破坏异常"); } } System.out.println(Thread.currentThread().getName()+"ok"); } public static Singleton2 getInstance(){ //先检查实例是否存在,如果不存在才进入下面的同步块 if(instance == null){ //同步块,线程安全的创建实例 synchronized (Singleton2.class) { //再次检查实例是否存在,如果不存在才真正的创建实例 if(instance == null){ instance = new Singleton2();//不是一个原子性操作 } } } return instance; } }
缺点:会被反射调用方法破环,生成不止单例,可以通过枚举类进行防护或者如上述代码设计一个私有boolean属性作为判断
工厂模式:创建一个工厂用来实例化对象,、一个调用者想创建一个对象,只要知道其名称就可以了,屏蔽产品的具体实现,调用者只关心产品的接口,具有高的扩展性
例:
Car接口
public interface Car { public void carName(); }
Car实现类
public class Wuling implements Car { @Override public void carName() { System.out.println("Wuling"); } }
工厂类
public class CarFactory { public static Car getCar(String name){ if (name.equals("DaZhong")){ return new DaZhong(); }else if (name.equals("Wuling")){ return new Wuling(); }else{ return null; } } }
实现了创建者和调用者的分离。
应用场景
1、JDk中Calendar的getInstance方法
2、JDBC中的Connection对象的获取
3、Spring中IOC容器创建管理bean对象
4、反射中Class对象的newInstance方法