java框架基础(4)

设计模式之单例、工厂

单例模式:确保某一个类在系统中只有一个实例,并自行实例化,同时向外部提供获取这个唯一实例的接口

饿汉式:

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方法

原文地址:https://www.cnblogs.com/lzj-learn/p/14679777.html