深入理解与应用工厂方法模式

文章目录

一、模式概述

​ 工厂方法模式是一种经典的设计模式,它遵循面向对象的设计原则,特别是"开闭原则",通过定义一个用于创建对象的接口,将对象的实例化过程推迟到子类中实现。这种模式与抽象工厂模式类似,但更加专注于对单一接口下产品类型的创建。

二、适用场景

  • 复杂对象的创建需要大量重复代码时。
  • 对象创建依赖于外部资源或信息。
  • 需要统一管理对象生命周期,如会话、资源池对象等。
  • 需要隐藏对象的具体类型,提高代码的抽象层次。

以 MyBatis 的 LogFactory 类为例,展示了工厂方法模式如何应用于实际项目中,通过灵活的选择和初始化不同日志实现类(如 Slf4j、Log4j 等),达到按需创建和管理日志对象的目的。

三、模式原理与实现

​ 工厂方法模式的核心在于封装对象的创建过程,提高对象创建的可复用性。通过观察代码实现可知,核心工厂类并不直接创建具体产品,而是通过判断条件委派给子类,从而使得在不修改核心工厂的前提下能够引入新的产品实现。

工厂方法模式的核心组成部分包括:

  1. 抽象产品(Abstract Product) :定义产品的公共接口,如 IProduct 接口。
  2. 核心工厂(Concrete Factory) :如 ProductFactory 类,提供创建产品实例的通用接口,根据传入的参数决定创建何种具体产品。
  3. 具体产品(Concrete Products) :如 Product_A_ImplProduct_B_Impl 类,它们实现抽象产品接口,提供了具体产品的实例化过程。

以下是工厂方法模式的一个详细代码示例,创建一个动物工厂,它可以创建各种类型的动物对象:

首先,我们定义一个抽象的动物接口(抽象产品):

java 复制代码
// 抽象产品
public interface Animal {
    void makeSound();
}

然后,我们创建几个实现了 Animal 接口的具体动物类(具体产品):

java 复制代码
// 具体产品:Dog 类
public class Dog implements Animal {
    @Override
    public void makeSound() {
        System.out.println("Woof! Woof!");
    }
}

// 具体产品:Cat 类
public class Cat implements Animal {
    @Override
    public void makeSound() {
        System.out.println("Meow! Meow!");
    }
}

接下来,我们定义一个抽象工厂类,它声明了一个创建动物对象的方法:

java 复制代码
// 抽象工厂
public abstract class AnimalFactory {
    public abstract Animal createAnimal(String animalType);
}

然后,我们创建两个具体工厂类,它们实现了上述抽象工厂类,并在其中定义了如何创建具体动物对象:

java 复制代码
// 具体工厂:DogFactory 类
public class DogFactory extends AnimalFactory {
    @Override
    public Animal createAnimal(String animalType) {
        if ("dog".equalsIgnoreCase(animalType)) {
            return new Dog();
        }
        throw new IllegalArgumentException("Invalid animal type");
    }
}

// 具体工厂:CatFactory 类
public class CatFactory extends AnimalFactory {
    @Override
    public Animal createAnimal(String animalType) {
        if ("cat".equalsIgnoreCase(animalType)) {
            return new Cat();
        }
        throw new IllegalArgumentException("Invalid animal type");
    }
}

最后,我们通过客户端代码来演示如何使用工厂方法模式创建并使用动物对象:

java 复制代码
public class Client {
    public static void main(String[] args) {
        // 使用 DogFactory 创建 Dog 对象
        AnimalFactory dogFactory = new DogFactory();
        Animal dog = dogFactory.createAnimal("dog");
        dog.makeSound();  // 输出:Woof! Woof!

        // 使用 CatFactory 创建 Cat 对象
        AnimalFactory catFactory = new CatFactory();
        Animal cat = catFactory.createAnimal("cat");
        cat.makeSound();  // 输出:Meow! Meow!
    }
}

测试结果

​ 在这个示例中,AnimalFactory 是抽象工厂,DogFactoryCatFactory 是具体工厂,DogCat 是具体产品。客户端代码通过工厂方法来获取具体产品,而无需直接创建产品对象,这样就实现了对象的创建和使用相分离,同时也易于扩展新的产品类型。

四、采用工厂方法模式的原因

  1. 分离对象创建与使用:降低耦合性,增强代码的可维护性与可扩展性。
  2. 减少重复代码:通过工厂类集中处理相似对象的创建逻辑,避免代码冗余。
  3. 管理创建逻辑的变化:当业务逻辑发生变化时,只需修改工厂类的实现,无需改动大量调用处。

五、优缺点分析

  • 优点:支持灵活定制,隐藏实现细节,符合开闭原则,实现多态性。
  • 缺点:当抽象接口新增方法时,可能导致所有具体工厂都要相应修改;若具体工厂实现逻辑各异,则增加代码理解和维护难度。

六、与抽象工厂模式的比较

​ 尽管工厂方法模式与抽象工厂模式都属于创建型设计模式,但前者更关注于单一接口下产品的创建与替换,强调继承结构的连续性;而后者聚焦于一组相关产品间的协同创建,更看重组合的扩展性,两种模式在实际应用中各有侧重。

总结

​ 工厂方法模式以其简洁的实现和良好的扩展性,在实际项目中广泛使用。在面临对象创建逻辑较为复杂或需要灵活切换产品实现时,它是一种值得考虑的设计解决方案。然而,在简单对象创建场景下,开发者需审慎使用,避免因过度设计引入额外复杂性。

相关推荐
小金的学习笔记3 分钟前
隐藏指定文件/文件夹和自动提示功能消失解决方案
java·idea
Q_19284999064 分钟前
基于Spring Boot的个性化推荐外卖点餐系统
java·spring boot·后端
会说法语的猪17 分钟前
IDEA使用Alt + Enter快捷键自动接受返回值一直有final修饰的问题处理
java·ide·intellij-idea
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ26 分钟前
MyBatis执行完sql后,返回的数值代表的意思
java·开发语言
思忖小下1 小时前
梳理你的思路(从OOP到架构设计)_设计模式Composite模式
设计模式·组合模式·eit
CodeClimb1 小时前
【华为OD-E卷-寻找密码 100分(python、java、c++、js、c)】
java·python·华为od
爱上语文1 小时前
宠物管理系统:Service层
java·开发语言·宠物
机器视觉知识推荐、就业指导1 小时前
C++设计模式:组合模式(公司架构案例)
c++·后端·设计模式·组合模式
水w1 小时前
【项目实践】SpringBoot Nacos配置管理 map数据
java·服务器·开发语言·spring boot·nacos
@菜鸟进阶记@1 小时前
SpringBoot核心:自动配置
java·spring boot·后端