创建型模式介绍
创建型模式:
一. 单例模式 :
应用场景:
Windows的任务管理器
Windows的垃圾回收站
数据库连接池的设计一般是单例模式
Spring中,每个Bean默认是单例的
Servlet编程中,每个Servlet是单例的
常见的五种单例模式实现方式 :
1. 饿汉式 :(线程安全,调用效率高,不能延迟加载)
2. 懒汉式 :(线程安全,调用效率不高,可以延迟加载)
3. DCL懒汉式 :(由于JVM底层内部模型原因,偶尔会出现问题,不建议使用)
4. 饿汉式改进 :静态内部类式(线程安全,调用效率高,可以延迟加载)
5. 枚举单例 : (线程安全,调用效率高,不能延迟加载)
//饿汉式单例
public class Singleton {
/* 如果加了一些开辟内存空间的方式,类加不加在都初始化了,浪费空间
private byte[] data1 = new byte[1024];
private byte[] data2 = new byte[1024];
private byte[] data3 = new byte[1024];
private byte[] data4 = new byte[1024];
*/
//1. 私有化构造器
private Singleton(){}
//2. 类初始化时候,立即加载该对象
private static Singleton instance = new Singleton();
//3. 提供获取该对象的方法,没有synchronized 效率高!
public static Singleton getInstance(){
return instance;
}
}
//懒汉式单例
public class Singleton {
//1. 私有化构造器
private Singleton(){}
//2. 类初始化时候,不立即加载该对象
private static Singleton instance;
//3. 提供获取该对象的方法,没有synchronized 效率高!
public static synchronized Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
//DCL懒汉式单例
public class Singleton {
//1. 私有化构造器
private Singleton(){}
//2. 类初始化时候,不立即加载该对象
private static volatile Singleton instance;
//3. 提供获取该对象的方法,没有synchronized 效率高!
public static Singleton getInstance(){
if (instance == null) {
synchronized(Singleton.class){
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
** 1.分配内存 2. 执行构造方法 3. 指向内存
因为不是原子性,在 synchronized 代码块中可能会出现问题
可以在初始化对象加个 volatile 关键字 也有可能出现问题
//静态内部类式单例
public class Singleton {
private Singleton(){}
private static class InnerClass{
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance(){
return InnerClass.instance;
}
}
// 但是可以通过反射机制来破坏 private
public static void main(String[] args) throws Exception {
Constructor<Singleton> declaredConstructor = Singleton.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
Singleton instance = declaredConstructor.newInstance();
}
// 如果第一次不使用反射创建对象
// 可以在私有构造器中用同步代码判断对象是否为空来实现单例
// 两次都用反射创建时可以
private static boolean flag = false;
private Singleton(){
synchronized (Singleton.class){
if (flag == false) {
flag = true;
}else{
throw new RuntimeException("xxxx");
}
}
}
** 但是也可以利用反射来破坏flag, 或者序列化到文本在反序列化
// 枚举
public enum Singleton {
INSTANCE;
public Singleton getInstance(){
return INSTANCE;
}
}
二. 工厂模式 :
OOP七大原则:
1.开闭原则(实体对拓展开放,对修改关闭)
2.依赖倒转原则(要针对接口编程,不要针对实现编程)
3. 迪米特法则(与直接关联的通信,不与陌生通信)
应用场景:
Spring中IOC容器创建管理的Bean对象
反射中Class对象的newInstance方法
JDBC的Connection对象获取
1. 简单工厂模式 :用来生产同一等级结构的任意产品(对于新加的产品,需要拓展已有代码)
2. 工厂方法模式 :用来生产同一等级结构中的固定产品(支持增加任意产品)
3. 抽象工厂模式 :围绕一个超级工厂创建其他工厂,该超级工厂又称其他工厂的工厂
// 简单工厂模式
public class CarFactory{
public static Car getCar(String carName) {
if (carName.equals("xxx")){
return new xxx();
}else if(carName.equals("xxxx")){
return new xxxx();
}else
return null;
}
}
** 而工厂方式模式 要每一个类都要有一个Factory工厂来实现对象初始化 保证了横向拓展 也不用改动
** 抽象工厂模式