1 设计原则
1.1 开闭原则
对扩展开放,对修改关闭 (代表:接口)
1.2 里氏代换原则
尽量不重写父类代码(举例:正方行类不继承自长方形类)
1.3 依赖倒转原则
高层模块不依赖底层模块 (原则:都应依赖于其抽象),降低客户与实现类之间的耦合
1.4 接口隔离原则
各个功能模块相隔离,比如电脑a有dvd,而电脑b没有dvd,故而需要dvd为单独的接口,其他硬件同理
1.5迪米特法则
最少知识原则,如果两个实体之间无需通讯,如体育老师和数学老师,那么久不应该发生相互调用,需要调用时应当采用第三方间接调用(目的:提高耦合性)
1.6合成复用原则
尽量使用组合或聚合关联关系(合成复用),退而求其次才选择继承关系(继承复用)
2 创建者模式
2.1 单例设计模式
此模式提供了创建对象的最佳方式
思想:创建一个类,此类负责创建自己的对象,同时确保只有单个对象被创建。提供一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
结构:
两个类:
- 单例类(只能创建一个实例)
- 访问类(使用单例类)
种类:
- 饿汉式
public class Singleton {
//私有构造方法
private Singleton() {}
//在成员位置创建该类的对象
private static Singleton instance = new Singleton();
//对外提供静态方法获取该对象
public static Singleton getInstance() {
return instance;
}
}
public class Singleton {
//私有构造方法
private Singleton() {}
//在成员位置创建该类的对象
private static Singleton instance;
static {
instance = new Singleton();
}
//对外提供静态方法获取该对象
public static Singleton getInstance() {
return instance;
}
}
- 懒汉式
//线程不安全
public class Singleton {
//私有构造方法
private Singleton() {}
//在成员位置创建该类的对象
private static Singleton instance;
//对外提供静态方法获取该对象
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
//线程安全
public class Singleton {
//私有构造方法
private Singleton() {}
//在成员位置创建该类的对象
private static Singleton instance;
//对外提供静态方法获取该对象
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
//双重检查方式
public class Singleton {
//私有构造方法
private Singleton() {}
private static Singleton instance;
//对外提供静态方法获取该对象
public static Singleton getInstance() {
//第一次判断,如果instance不为null,不进入抢锁阶段,直接返回实例
if(instance == null) {
synchronized (Singleton.class) {
//抢到锁之后再次判断是否为null
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
//考虑到jvm优化和指令重排导致的空指针异常的双重检查方式
public class Singleton {
//私有构造方法
private Singleton() {}
//使用了volatile关键字
private static volatile Singleton instance;
//对外提供静态方法获取该对象
public static Singleton getInstance() {
//第一次判断,如果instance不为null,不进入抢锁阶段,直接返回实际
if(instance == null) {
synchronized (Singleton.class) {
//抢到锁之后再次判断是否为空
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
添加 volatile
关键字之后的双重检查锁模式是一种比较好的单例实现模式,能够保证在多线程的情况下线程安全也不会有性能问题。
/**
* 静态内部类方式
*/
public class Singleton {
//私有构造方法
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
//对外提供静态方法获取该对象
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
说明:
第一次加载Singleton类时不会去初始化INSTANCE,只有第一次调用getInstance,虚拟机加载SingletonHolder
并初始化INSTANCE,这样不仅能确保线程安全,也能保证 Singleton 类的唯一性。
小结:
静态内部类单例模式是一种优秀的单例模式,是开源项目中比较常用的一种单例模式。在没有加任何锁的情况下,保证了多线程下的安全,并且没有任何性能影响和空间的浪费。
- 枚举方式(饿汉式方式)
/**
* 枚举方式
* 线程安全
*/
public enum Singleton {
INSTANCE;
}
破坏单例模式:
使上面定义的单例类(Singleton)可以创建多个对象,枚举方式除外。有两种方式,分别是序列化和反射。
防止破坏的方法:
public class Singleton implements Serializable {
//私有构造方法
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
//对外提供静态方法获取该对象
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
/**
* 下面是为了解决序列化反序列化破解单例模式
*/
private Object readResolve() {
return SingletonHolder.INSTANCE;
}
}
public class Singleton {
//私有构造方法
private Singleton() {
/*
反射破解单例模式需要添加的代码
*/
if(instance != null) {
throw new RuntimeException();
}
}
private static volatile Singleton instance;
//对外提供静态方法获取该对象
public static Singleton getInstance() {
if(instance != null) {
return instance;
}
synchronized (Singleton.class) {
if(instance != null) {
return instance;
}
instance = new Singleton();
return instance;
}
}
}