一、单例模式
作用:实现一个类只有一个实例化对象,提供一个全局访问点
原理:
- 通过创建私有变量在内部实例化
- 私有化构造方法
- 外部通过调用定义的公有方法返回唯一实例
懒汉式
类加载时没有生成单例,只有当第一次调用 getInstance()
方法才去创建单例
public class LazySingleton {
// 防止
private static volatile LazySingleton lazySingleton = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
// 如果是多线程环境,使用DCL锁,保证线程安全,即每次都是同一个对象
if (null == lazySingleton) {
synchronized (LazySingleton.class) {
if (null == lazySingleton) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
lazySingleton = new LazySingleton();
}
}
}
return lazySingleton;
}
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
new Thread(() -> System.out.println(LazySingleton.getInstance().hashCode())).start();
}
}
}
饿汉式
该模式的特点是类一旦加载就创建一个单例,保证在调用 getInstance()
方法之前单例已经存在了
public class HungrySingleton {
private static final HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return instance;
}
}
二、工厂方法模式
工厂方法模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟都具体工厂类中。当满足创建型模式中所要求的”创建与使用相分离“的特点。
我们把被创建的对象成为“产品“,把创建产品的对象成为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式键“简单工厂模式”,它不属于23种经典设计模式,它的缺点是增加新产品时会违背“开闭原则”。
简单工厂模式
- 含义:简单工厂模式又叫静态方法模式(因为工厂类定义了一个静态方法)
- 解决的问题:使用者可直接消费产品而不需要知道其生产的细节
步骤1:创建抽象产品类 & 定义具体产品的公共接口;
步骤2:创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
步骤3:创建工厂类,通过创建静态方法根据传入不同参数从而创建不同具体产品类的实例;
步骤4:外界通过调用工厂类的静态方法,传入不同参数从而创建不同具体产品类的实例
工厂方法模式
步骤1:创建抽象工厂类,定义具体工厂的公共接口;
步骤2:创建抽象产品类 ,定义具体产品的公共接口;
步骤3:创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
步骤4:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
步骤5:外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例
三、抽象工厂模式
步骤1:创建抽象工厂类,定义具体工厂的公共接口;
步骤2:创建抽象产品族类 ,定义抽象产品的公共接口;
步骤3:创建抽象产品类 (继承抽象产品族类),定义具体产品的公共接口;
步骤4:创建具体产品类(继承抽象产品类)& 定义生产的具体产品;
步骤5:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
**步骤6:**客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例
四、建造者模式
**作用:**隐藏创建对象的细节,降低创建单个对象的复杂度
**应用场景:**当一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,考虑使用构造者模式。
/**
* Builder模式
* 1. 在User中创建一个静态内部类Builder,然后将User中的参数都复制到Builder类中。
* 2. 在User中创建一个private的构造函数,参数为Builder类型。
* 3. 在Builder中创建一个public的构造函数,参数为User中必填的那些参数。
* 4. 在Builder中创建设置函数,对User中那些可选参数进行赋值,返回值为Builder类型的实例。
* 5. 在Builder中创建一个build()方法,在其中构建User的实例并返回。
* @author kangyw41748
* @date 2023/1/11
*/
public class User {
private final String username; // 必填
private final String password; // 必填
private final String nickname; // 可选
private final String birthday; // 可选
public static Builder builder(String username, String password) {
return new Builder(username, password);
}
public static class Builder {
private final String username; // 必填
private final String password; // 必填
private String nickname; // 可选
private String birthday; // 可选
public Builder(String username, String password) {
this.username = username;
this.password = password;
}
public Builder nickname(String nickname) {
this.nickname = nickname;
return this;
}
public Builder birthday(String birthday) {
this.birthday = birthday;
return this;
}
public User build() {
return new User(this);
}
}
private User(Builder builder) {
this.username = builder.username;
this.password = builder.password;
this.nickname = builder.nickname;
this.birthday = builder.birthday;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getNickname() {
return nickname;
}
public String getBirthday() {
return birthday;
}
}