4.创建者模式
4.1单例模式
1.饿汉式
/**
* @Author: kirito
* @Date: 2024/3/8 10:54
* @Description: 饿汉式静态代码块
*/
public class Singleton {
//私有构造方法
private Singleton() {
}
//声明变量
private static Singleton instance;
//在静态代码块中复制
static {
instance = new Singleton();
}
public static Singleton getInstance() {
return instance;
}
}
/**
* @Author: kirito
* @Date: 2024/3/8 10:54
* @Description: 饿汉式静态成员变量
*/
public class Singleton {
private Singleton() {
}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
该方式在成员位置声明singleton类型的静态变量,而对象的创建是在静态代码块中,也是对着类的加载而创建。所以和饿汉式的方式l基本上一样,当然该方式也存在内存浪费问题。
2.懒汉式(双重检查锁)
public class Singleton {
private Singleton() {}
//这里要加volatile 否则有问题
private static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
return new Singleton();
}
}
}
return instance;
}
}
注意!!!👇
- 禁止指令重排序:在没有volatile修饰的情况下,处理器可能会对指令进行重排序以提高性能。这可能导致某些线程在第一次条件判断之前看到的是一个非空但尚未完全初始化的对象,从而违反了单例模式的规则。使用volatile关键字可以防止这种情况的发生,确保每个线程看到的对象状态是一致的。
确保可见性:volatile关键字强制线程从主内存读取变量的最新值,而不是依赖本地的缓存副本。这样做的目的是确保不同线程之间对共享数据的更新和读取是可见的。
确保有序性:volatile同样有助于维护程序的执行顺序,尽管它本身不能保证原子性。在双重检查锁的场景中,volatile的使用有助于确保特定操作的顺序,如首先判断单例对象是否为空,然后再尝试创建新对象。
3.懒汉式(静态内部类)
/**
* @Author: kirito
* @Date: 2024/3/8 11:17
* @Description: 静态内部类
*
* 外部类加载时并不需要立即加载内部类,内部类不被加载则不去初始化INSTANCE,
* 故而不占内存。即当SingleTon第一次被加载时,并不需要去加载SingleTonHoler,
* 只有当getInstance()方法第一次被调用时,才会去初始化INSTANCE,
* 第一次调用getInstance()方法会导致虚拟机加载SingleTonHoler类,
* 这种方法不仅能确保线程安全,也能保证单例的唯一性,同时也延迟了单例的实例化。
*
*/
public class Singleton {
private Singleton() {}
//定义一个静态内部类
private static class SingletonBuilder {
//在内部类中声明并初始化外部类对象
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonBuilder.INSTANCE;
}
}
4.枚举
4.2工厂方法模式
虽然工厂模式方法能够解决对于对象创造的强耦合度,但是对于工厂的耦合度又上去了,这种思想有点像分层一样,对象可能是最底层的东西,但是尽可能不要直接去创建,而是通过一个中间层去创建对象,这样方便管理。。。感觉是这么个理解的意思
然后中间层又相当于是一个只会扩展的层次,不会修改功能,所以对于已经在使用的了应用层的业务代码不会受影响,所以这样抽出方法框架来写代码更好维护
4.3抽象工厂模式
4.4原型模式
public class Realizetype implements Cloneable {
public Realizetype() {
System.out.println("具体的原型对象创建完成!");
}
@Override
protected Realizetype clone() throws CloneNotSupportedException {
System.out.println("具体原型复制成功!");
return (Realizetype) super.clone();
}
}
public class PrototypeTest { public static void main(String[] args) throws CloneNotSupportedException { Realizetype r1 = new Realizetype(); Realizetype r2 = r1.clone(); System.out.println("对象r1和r2是同一个对象?" + (r1 == r2)); } }
用原型模式生成“三好学生”奖状
同一学校的“三好学生”奖状除了获奖人姓名不同,其他都相同,可以使用原型模式复制多个“三好学生”奖状出来,然后在修改奖状上的名字即可。
//奖状类
public class Citation implements Cloneable {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return (this.name);
}
public void show() {
System.out.println(name + "同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!");
}
@Override
public Citation clone() throws CloneNotSupportedException {
return (Citation) super.clone();
}
}
//测试访问类
public class CitationTest {
public static void main(String[] args) throws CloneNotSupportedException {
Citation c1 = new Citation();
c1.setName("张三");
//复制奖状
Citation c2 = c1.clone();
//将奖状的名字修改李四
c2.setName("李四");
c1.show();
c2.show();
}
}
4.5建造者模式
建造者(Builder)模式包含如下角色:
抽象建造者类(Builder):这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的部件对象的创建。
具体建造者类(ConcreteBuilder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。在构造过程完成后,提供产品的实例。
产品类(Product):要创建的复杂对象。
指挥者类(Director):调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。