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

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

设计模式是软件开发中解决常见问题的可复用方案。本文将详细介绍两种种重要的创建型设计模式:工厂模式、单例模式,并提供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 适用场景

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

总结

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

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

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

相关推荐
xosg4 小时前
嵌入式<style>设计模式
设计模式
得不到的更加爱4 小时前
设计模式总结
设计模式
清霜之辰5 小时前
安卓开发用到的设计模式(2)结构型模式
android·设计模式·结构型设计模式
长勺5 小时前
单例模式总结
java·开发语言·单例模式
总是难免6 小时前
设计模式 - 模板方法模式
java·设计模式·模板方法模式
琢磨先生David9 小时前
《Java 单例模式:从类加载机制到高并发设计的深度技术剖析》
java·设计模式
YGGP9 小时前
【创造型模式】单例模式
单例模式
沐土Arvin10 小时前
Web 安全进阶:前端信封加解密技术详解
前端·javascript·安全·设计模式
zizisuo12 小时前
Java集合框架深度剖析:结构、并发与设计模式全解析
java·javascript·数据结构·设计模式