跳转至

Java 工厂模式示例:从基础到最佳实践

简介

在 Java 开发中,设计模式是解决常见问题的通用方案。工厂模式作为一种创建型设计模式,它提供了一种创建对象的方式,将对象的创建和使用分离。通过使用工厂模式,我们可以提高代码的可维护性、可扩展性以及可测试性。本文将详细介绍 Java 工厂模式示例,包括基础概念、使用方法、常见实践以及最佳实践。

目录

  1. 工厂模式基础概念
  2. 使用方法
    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式
  3. 常见实践
  4. 最佳实践
  5. 小结
  6. 参考资料

工厂模式基础概念

工厂模式是一种创建对象的设计模式,它把对象的创建逻辑封装在一个工厂类中,而不是在客户端代码中直接实例化对象。这样做的好处是,如果对象的创建过程发生变化,只需要修改工厂类,而不需要修改所有使用该对象的客户端代码。

工厂模式主要有三种类型: - 简单工厂模式:简单工厂模式是工厂模式的基础,它定义了一个工厂类,用于创建产品对象。简单工厂模式不属于 GOF 23 种设计模式,但它是工厂方法模式和抽象工厂模式的基础。 - 工厂方法模式:工厂方法模式在简单工厂模式的基础上,将创建方法抽象成抽象方法,由具体的工厂子类实现。这样,当需要创建新的产品对象时,只需要创建一个新的工厂子类,而不需要修改工厂类的代码。 - 抽象工厂模式:抽象工厂模式提供了一个创建一系列相关或依赖对象的接口,而不需要指定它们具体的类。抽象工厂模式的工厂类创建的不是一个简单的产品对象,而是一系列相关的产品对象。

使用方法

简单工厂模式

简单工厂模式包含三个角色: - 工厂类(Creator):负责创建产品对象。 - 产品类(Product):定义了产品的接口或抽象类。 - 具体产品类(ConcreteProduct):实现了产品接口或继承了产品抽象类。

以下是一个简单工厂模式的示例代码:

// 产品类
interface Product {
    void operation();
}

// 具体产品类
class ConcreteProduct implements Product {
    @Override
    public void operation() {
        System.out.println("这是具体产品的操作");
    }
}

// 工厂类
class SimpleFactory {
    public static Product createProduct() {
        return new ConcreteProduct();
    }
}

// 客户端代码
public class SimpleFactoryClient {
    public static void main(String[] args) {
        Product product = SimpleFactory.createProduct();
        product.operation();
    }
}

工厂方法模式

工厂方法模式在简单工厂模式的基础上,将创建方法抽象成抽象方法,由具体的工厂子类实现。工厂方法模式包含四个角色: - 抽象工厂类(Creator):定义了创建产品对象的抽象方法。 - 具体工厂类(ConcreteCreator):实现了抽象工厂类的抽象方法,创建具体的产品对象。 - 产品类(Product):定义了产品的接口或抽象类。 - 具体产品类(ConcreteProduct):实现了产品接口或继承了产品抽象类。

以下是一个工厂方法模式的示例代码:

// 产品类
interface Product {
    void operation();
}

// 具体产品类
class ConcreteProduct1 implements Product {
    @Override
    public void operation() {
        System.out.println("这是具体产品1的操作");
    }
}

class ConcreteProduct2 implements Product {
    @Override
    public void operation() {
        System.out.println("这是具体产品2的操作");
    }
}

// 抽象工厂类
abstract class Factory {
    public abstract Product createProduct();
}

// 具体工厂类
class ConcreteFactory1 extends Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProduct1();
    }
}

class ConcreteFactory2 extends Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProduct2();
    }
}

// 客户端代码
public class FactoryMethodClient {
    public static void main(String[] args) {
        Factory factory1 = new ConcreteFactory1();
        Product product1 = factory1.createProduct();
        product1.operation();

        Factory factory2 = new ConcreteFactory2();
        Product product2 = factory2.createProduct();
        product2.operation();
    }
}

抽象工厂模式

抽象工厂模式提供了一个创建一系列相关或依赖对象的接口,而不需要指定它们具体的类。抽象工厂模式包含五个角色: - 抽象工厂类(AbstractFactory):定义了创建一系列产品对象的抽象方法。 - 具体工厂类(ConcreteFactory):实现了抽象工厂类的抽象方法,创建具体的产品对象。 - 抽象产品类(AbstractProduct):定义了产品的接口或抽象类。 - 具体产品类(ConcreteProduct):实现了抽象产品类的接口或继承了抽象产品类。 - 客户端(Client):使用抽象工厂类和抽象产品类来创建和使用产品对象。

以下是一个抽象工厂模式的示例代码:

// 抽象产品类A
interface AbstractProductA {
    void operationA();
}

// 具体产品类A1
class ConcreteProductA1 implements AbstractProductA {
    @Override
    public void operationA() {
        System.out.println("这是具体产品A1的操作");
    }
}

// 具体产品类A2
class ConcreteProductA2 implements AbstractProductA {
    @Override
    public void operationA() {
        System.out.println("这是具体产品A2的操作");
    }
}

// 抽象产品类B
interface AbstractProductB {
    void operationB();
}

// 具体产品类B1
class ConcreteProductB1 implements AbstractProductB {
    @Override
    public void operationB() {
        System.out.println("这是具体产品B1的操作");
    }
}

// 具体产品类B2
class ConcreteProductB2 implements AbstractProductB {
    @Override
    public void operationB() {
        System.out.println("这是具体产品B2的操作");
    }
}

// 抽象工厂类
abstract class AbstractFactory {
    public abstract AbstractProductA createProductA();
    public abstract AbstractProductB createProductB();
}

// 具体工厂类1
class ConcreteFactory1 extends AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ConcreteProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }
}

// 具体工厂类2
class ConcreteFactory2 extends AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ConcreteProductA2();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ConcreteProductB2();
    }
}

// 客户端代码
public class AbstractFactoryClient {
    public static void main(String[] args) {
        AbstractFactory factory1 = new ConcreteFactory1();
        AbstractProductA productA1 = factory1.createProductA();
        AbstractProductB productB1 = factory1.createProductB();
        productA1.operationA();
        productB1.operationB();

        AbstractFactory factory2 = new ConcreteFactory2();
        AbstractProductA productA2 = factory2.createProductA();
        AbstractProductB productB2 = factory2.createProductB();
        productA2.operationA();
        productB2.operationB();
    }
}

常见实践

  1. 对象创建逻辑复杂时:当对象的创建过程涉及到多个步骤、复杂的配置或者需要处理异常时,使用工厂模式将创建逻辑封装在工厂类中,可以使客户端代码更加简洁,易于维护。
  2. 根据不同条件创建对象:在实际开发中,经常需要根据不同的条件创建不同类型的对象。例如,根据用户的权限创建不同的用户对象,或者根据系统配置创建不同的数据库连接对象。工厂模式可以很好地满足这种需求,通过在工厂类中添加判断逻辑,根据不同的条件创建不同的对象。
  3. 代码解耦:使用工厂模式可以将对象的创建和使用分离,降低代码之间的耦合度。当对象的创建过程发生变化时,只需要修改工厂类,而不需要修改所有使用该对象的客户端代码。这样可以提高代码的可维护性和可扩展性。

最佳实践

  1. 遵循单一职责原则:工厂类应该只负责对象的创建,不应该包含与对象创建无关的业务逻辑。这样可以使工厂类的职责更加单一,易于维护和扩展。
  2. 使用依赖注入:在工厂类中,可以使用依赖注入的方式将创建对象所需的依赖项注入到工厂类中。这样可以提高代码的灵活性和可测试性。
  3. 缓存创建的对象:如果创建对象的过程比较耗时或者资源消耗较大,可以在工厂类中缓存已经创建的对象,避免重复创建。这样可以提高系统的性能。
  4. 使用泛型:在工厂类中,可以使用泛型来提高代码的通用性和可复用性。例如,创建一个通用的工厂类,可以根据传入的类型参数创建不同类型的对象。

小结

本文详细介绍了 Java 工厂模式的基础概念、使用方法、常见实践以及最佳实践。通过使用工厂模式,我们可以将对象的创建和使用分离,提高代码的可维护性、可扩展性以及可测试性。在实际开发中,我们应该根据具体的需求选择合适的工厂模式,并遵循最佳实践,以提高代码的质量和性能。

参考资料