深入理解设计模式:工厂模式、单例模式

深入理解设计模式:工厂模式、单例模式

设计模式是软件开发中解决常见问题的可复用方案。本文将详细介绍两种种重要的创建型设计模式:工厂模式、单例模式,并提供Java实现示例。

一、工厂模式

工厂模式是一种创建对象的设计模式,它提供了一种创建对象的最佳方式,而无需向客户端暴露创建逻辑。

1.1 简单工厂模式

简单工厂模式由一个工厂类负责创建所有产品。

java 复制代码
// 产品接口
interface Product {
    void operation();
}

// 具体产品A
class ConcreteProductA implements Product {
    @Override
    public void operation() {
        System.out.println("ConcreteProductA operation");
    }
}

// 具体产品B
class ConcreteProductB implements Product {
    @Override
    public void operation() {
        System.out.println("ConcreteProductB operation");
    }
}

// 简单工厂
class SimpleFactory {
    public static Product createProduct(String type) {
        if ("A".equals(type)) {
            return new ConcreteProductA();
        } else if ("B".equals(type)) {
            return new ConcreteProductB();
        }
        throw new IllegalArgumentException("Unknown product type");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Product productA = SimpleFactory.createProduct("A");
        productA.operation();
        
        Product productB = SimpleFactory.createProduct("B");
        productB.operation();
    }
}

1.2 工厂方法模式

工厂方法模式将实际创建对象的责任委托给子类。

java 复制代码
// 产品接口
interface Product {
    void operation();
}

// 具体产品A
class ConcreteProductA implements Product {
    @Override
    public void operation() {
        System.out.println("ConcreteProductA operation");
    }
}

// 具体产品B
class ConcreteProductB implements Product {
    @Override
    public void operation() {
        System.out.println("ConcreteProductB operation");
    }
}

// 工厂接口
interface Factory {
    Product createProduct();
}

// 具体工厂A
class ConcreteFactoryA implements Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

// 具体工厂B
class ConcreteFactoryB implements Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProductB();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Factory factoryA = new ConcreteFactoryA();
        Product productA = factoryA.createProduct();
        productA.operation();
        
        Factory factoryB = new ConcreteFactoryB();
        Product productB = factoryB.createProduct();
        productB.operation();
    }
}

1.3 抽象工厂模式

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

java 复制代码
// 产品A接口
interface ProductA {
    void operationA();
}

// 产品B接口
interface ProductB {
    void operationB();
}

// 具体产品A1
class ConcreteProductA1 implements ProductA {
    @Override
    public void operationA() {
        System.out.println("ConcreteProductA1 operationA");
    }
}

// 具体产品A2
class ConcreteProductA2 implements ProductA {
    @Override
    public void operationA() {
        System.out.println("ConcreteProductA2 operationA");
    }
}

// 具体产品B1
class ConcreteProductB1 implements ProductB {
    @Override
    public void operationB() {
        System.out.println("ConcreteProductB1 operationB");
    }
}

// 具体产品B2
class ConcreteProductB2 implements ProductB {
    @Override
    public void operationB() {
        System.out.println("ConcreteProductB2 operationB");
    }
}

// 抽象工厂接口
interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}

// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA1();
    }
    
    @Override
    public ProductB createProductB() {
        return new ConcreteProductB1();
    }
}

// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA2();
    }
    
    @Override
    public ProductB createProductB() {
        return new ConcreteProductB2();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        AbstractFactory factory1 = new ConcreteFactory1();
        ProductA productA1 = factory1.createProductA();
        ProductB productB1 = factory1.createProductB();
        productA1.operationA();
        productB1.operationB();
        
        AbstractFactory factory2 = new ConcreteFactory2();
        ProductA productA2 = factory2.createProductA();
        ProductB productB2 = factory2.createProductB();
        productA2.operationA();
        productB2.operationB();
    }
}

1.4 工厂模式的优缺点

优点:

  • 封装了对象的创建过程,客户端无需了解具体产品类
  • 可以轻松添加新产品而不影响现有代码
  • 遵循开闭原则

缺点:

  • 引入了额外的类和接口,增加了系统复杂度
  • 在某些情况下可能会增加系统的抽象程度和理解难度

1.5 适用场景

  • 当一个类不知道它所需要创建的对象的类时
  • 当一个类希望由子类来指定它所创建的对象时
  • 当创建对象的过程涉及到复杂的业务逻辑时

二、单例模式

单例模式确保一个类只有一个实例,并提供一个全局访问点。

2.1 饿汉式单例

java 复制代码
public class EagerSingleton {
    // 在类加载时就创建实例
    private static final EagerSingleton INSTANCE = new EagerSingleton();
    
    // 私有构造函数,防止外部实例化
    private EagerSingleton() {
        // 防止通过反射创建多个实例
        if (INSTANCE != null) {
            throw new IllegalStateException("Singleton already initialized");
        }
    }
    
    // 提供全局访问点
    public static EagerSingleton getInstance() {
        return INSTANCE;
    }
    
    // 示例方法
    public void doSomething() {
        System.out.println("Singleton is doing something");
    }
}

2.2 懒汉式单例(线程安全)

java 复制代码
public class LazySingleton {
    // 初始不创建实例
    private static volatile LazySingleton instance;
    
    // 私有构造函数
    private LazySingleton() {
        // 防止通过反射创建多个实例
        if (instance != null) {
            throw new IllegalStateException("Singleton already initialized");
        }
    }
    
    // 提供全局访问点,使用双重检查锁定
    public static LazySingleton getInstance() {
        if (instance == null) {
            synchronized (LazySingleton.class) {
                if (instance == null) {
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }
    
    // 示例方法
    public void doSomething() {
        System.out.println("Singleton is doing something");
    }
}

2.3 枚举实现单例

java 复制代码
public enum EnumSingleton {
    INSTANCE;
    
    // 示例方法
    public void doSomething() {
        System.out.println("Enum Singleton is doing something");
    }
}

// 使用方式
public class Client {
    public static void main(String[] args) {
        EnumSingleton.INSTANCE.doSomething();
    }
}

2.4 静态内部类实现单例

java 复制代码
public class StaticInnerSingleton {
    // 私有构造函数
    private StaticInnerSingleton() {}
    
    // 静态内部类持有单例实例
    private static class SingletonHolder {
        private static final StaticInnerSingleton INSTANCE = new StaticInnerSingleton();
    }
    
    // 提供全局访问点
    public static StaticInnerSingleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
    
    // 示例方法
    public void doSomething() {
        System.out.println("Static inner class Singleton is doing something");
    }
}

2.5 单例模式的优缺点

优点:

  • 保证一个类只有一个实例,减少内存开销
  • 提供全局访问点,便于全局控制
  • 实例只创建一次,避免多次实例化的性能开销

缺点:

  • 不适用于变化频繁的对象
  • 单例模式的扩展有一定难度
  • 单例可能导致单一职责原则的违反

2.6 适用场景

  • 需要频繁创建和销毁的对象
  • 创建对象时耗时过多或耗费资源过多的对象
  • 工具类对象
  • 频繁访问数据库或文件的对象

总结

本文详细介绍了两种种常用的创建型设计模式:工厂模式、单例模式和建造者模式。它们各自有不同的应用场景:

  • 工厂模式:当需要将对象的创建与使用分离,或者需要创建一系列相关对象时使用。
  • 单例模式:当系统中需要保证一个类只有一个实例,并提供全局访问点时使用。

这些设计模式都是面向对象设计的重要工具,理解并正确应用它们可以帮助我们编写出更加灵活、可维护的代码。

相关推荐
电子科技圈3 分钟前
先进封装、芯粒架构和3D集成——先进异构集成亟需兼具标准化与定制化能力的互联及总线IP解决方案
tcp/ip·设计模式·架构·软件构建·代码规范·设计规范
触底反弹3 小时前
🤯 面试被问 AI Workflow 和 Agent 有啥区别?3 张图 + 2 段代码讲清楚!
人工智能·设计模式·面试
张小姐的猫20 小时前
【Linux】网络编程 —— HTTP协议(上)
linux·运维·服务器·网络·http·单例模式·策略模式
杨充1 天前
10.可测试性实战设计
设计模式·开源·代码规范
杨充1 天前
9.重构十二式的实战
设计模式·开源·代码规范
杨充1 天前
6.设计原则的全景图
设计模式·开源·全栈
杨充1 天前
2.面向对象的特性
设计模式
杨充1 天前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充1 天前
8.反模式与坏味道
设计模式·开源·代码规范
杨充1 天前
3.接口vs抽象类比较
设计模式