一、单例模式
1.懒汉模式:
模式定义:保证一个类只有一个实例,并且提供一个全局访问点
场景:重量级的对象,不需要多个实例,如线程池,数据库连接池。
懒汉模式:延迟加载,只有在真正使用的时候,才开始实例化。
1)线程安全问题
2)double check 加锁优化
3)指令重排问题 通过增加volatile关键字防止指令重排
示例代码:
public class LazySingletonTest {
public static void main(String[] args) {
new Thread( () -> {
LazySingleton instance = LazySingleton.getInstance();
System.out.println(instance);
}).start();
new Thread( () -> {
LazySingleton instance = LazySingleton.getInstance();
System.out.println(instance);
}).start();
}
}
class LazySingleton {
private static volatile LazySingleton instance;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (instance == null) {
synchronized (LazySingleton.class) {
if (instance == null) {
instance = new LazySingleton();
}
}
}
return instance;
}
}
2. 饿汉模式:
模式定义:类加载的初始化阶段就完成了实例的初始化。本质上就是借助于jvm类加载机制,保证实例的唯一性。
类加载过程:
1.加载二进制数据到内存中,生成对应的Class数据结构
2.连接:①验证 ②准备(给类的静态成员变量赋默认值) ③解析
3.初始化:给类的静态变量赋初值
只有在真正使用对应的类时,才会触发初始化,如(当前类是启动类即main函数所在类,直接进行new操作,访问静态属性、静态方法,用反射访问类,初始化一个类的子类等.)
示例代码:
public class HungrySingletonTest {
public static void main(String[] args) {
HungrySingleton instance = HungrySingleton.getInstance();
HungrySingleton instance1 = HungrySingleton.getInstance();
System.out.println(instance == instance1);
}
}
class HungrySingleton {
private static HungrySingleton instance = new HungrySingleton();
private HungrySingleton () {
}
public static HungrySingleton getInstance() {
return instance;
}
}
二、工厂方法模式
模式定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method 使得一个类的实例化延迟到子类才加载
应用场景:
1.当你不知道改使用对象的确切类型的时候
2.当你希望为类或框架提供扩展内部组件的方法时
主要优点:
1.将具体产品和创建者解耦
2.符合单一职责原则
3.符合开闭原则
示例代码:
public class FactoryMethod {
public static void main(String[] args) {
Application application = new ConcreteProductA();
Product product = application.getObject();
product.method1();
}
}
interface Product {
void method1();
}
class ProductA implements Product {
public void method1() {
System.out.println("ProjectA.method1 executed. ");
}
}
class ProductA1 implements Product {
public void method1() {
System.out.println("ProjectA1.method1 executed. ");
}
}
class SimpleFactory {
public static Product createProduct(String type) {
if ("0".equals(type)) {
return new ProductA();
} else if ("1".equals(type)) {
return new ProductA1();
} else {
return null;
}
}
}
abstract class Application {
abstract Product createProduct();
Product getObject() {
Product product = createProduct();
// ...
// ...
return product;
}
}
class ConcreteProductA extends Application {
@Override
Product createProduct() {
// ....
return new ProductA();
}
}
class ConcreteProductA1 extends Application {
@Override
Product createProduct() {
// ....
return new ProductA1();
}
}
三、抽象工厂模式
模式定义:
提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类
应用场景:
程序需要处理不同系列的相关产品,但是不希望它依赖于这些产品的具体类时,可以使用抽象工厂
优点:
1.可以确信你从工厂得到的产品彼此是兼容的
2.可以避免具体产品和客户端代码之间的紧密耦合
3.符合单一职责原则
4.符合开闭原则
示例代码:
public class AbstractFactoryTest {
public static void main(String[] args) {
IDatabaseUtils iDatabaseUtils = new OracleDatabaseUtils();
IConnection connection = iDatabaseUtils.getConnection();
connection.connect();
ICommand command = iDatabaseUtils.getCommand();
command.command();
}
}
interface IConnection {
void connect ();
}
interface ICommand {
void command();
}
interface IDatabaseUtils {
IConnection getConnection();
ICommand getCommand();
}
class MysqlConnection implements IConnection {
@Override
public void connect() {
System.out.println(" mysql connected. ");
}
}
class OracleConnection implements IConnection {
@Override
public void connect() {
System.out.println(" oracle connected. ");
}
}
class MysqlCommand implements ICommand {
@Override
public void command() {
System.out.println(" mysql command. ");
}
}
class OracleCommand implements ICommand {
@Override
public void command() {
System.out.println(" oracle command. ");
}
}
class MysqlDatabaseUtils implements IDatabaseUtils {
@Override
public IConnection getConnection() {
return new MysqlConnection();
}
@Override
public ICommand getCommand() {
return new MysqlCommand();
}
}
class OracleDatabaseUtils implements IDatabaseUtils {
@Override
public IConnection getConnection() {
return new OracleConnection();
}
@Override
public ICommand getCommand() {
return new OracleCommand();
}
}
四、建造者模式
模式定义:
将一个复杂对象的创建与表示分离,使得同样的构建过程可以创建不同的表示
应用场景:
1.需要生成的对象具有复杂的内部结构
2.需要生成的对象内部属性本身相互依赖
3.与不可变对象配合使用
优点:
1.建造者独立,易扩展
2.便于控制细节风险
示例代码:
public class ProductTest2 {
public static void main(String[] args) {
Product product = new Product.Builder().productName("xxx").companyName("xxx").part1("part1").part2("part2").part3("part3").build();
System.out.println(product);
}
}
class Product {
private final String productName;
private final String companyName;
private final String part1;
private final String part2;
private final String part3;
private final String part4;
// .....
public Product(String productName, String companyName, String part1, String part2, String part3, String part4) {
this.productName = productName;
this.companyName = companyName;
this.part1 = part1;
this.part2 = part2;
this.part3 = part3;
this.part4 = part4;
}
static class Builder {
private String productName;
private String companyName;
private String part1;
private String part2;
private String part3;
private String part4;
public Builder productName(String productName) {
this.productName = productName;
return this;
}
public Builder companyName(String companyName) {
this.companyName = companyName;
return this;
}
public Builder part1(String part1) {
this.part1 = part1;
return this;
}
public Builder part2(String part2) {
this.part2 = part2;
return this;
}
public Builder part3(String part3) {
this.part3 = part3;
return this;
}
public Builder part4(String part4) {
this.part4 = part4;
return this;
}
Product build() {
//
return new Product(this.productName, this.companyName, this.part1, this.part2, this.part3, this.part4);
}
}
@Override
public String toString() {
return "Product{" +
"productName='" + productName + '\'' +
", companyName='" + companyName + '\'' +
", part1='" + part1 + '\'' +
", part2='" + part2 + '\'' +
", part3='" + part3 + '\'' +
", part4='" + part4 + '\'' +
'}';
}
}