工厂模式
外观
工厂模式[编辑 | 编辑源代码]
工厂模式(Factory Pattern)是设计模式中最常用的创建型模式之一,其核心思想是通过一个公共接口隐藏对象实例化的具体逻辑,使代码更灵活、可维护。根据抽象程度不同,工厂模式可分为简单工厂模式、工厂方法模式和抽象工厂模式。
核心思想[编辑 | 编辑源代码]
工厂模式通过将对象的创建过程封装到一个单独的类(工厂类)中,实现以下目标:
- 解耦:客户端代码无需关心具体类的构造细节。
- 扩展性:新增产品类时只需修改工厂逻辑,无需改动客户端代码。
- 统一管理:复杂对象的创建逻辑集中处理(如依赖注入、配置读取)。
分类与实现[编辑 | 编辑源代码]
1. 简单工厂模式[编辑 | 编辑源代码]
最简单的一种实现,通过静态方法根据输入参数返回不同产品对象。
代码示例[编辑 | 编辑源代码]
// 产品接口
interface Animal {
void speak();
}
// 具体产品
class Dog implements Animal {
public void speak() { System.out.println("Woof!"); }
}
class Cat implements Animal {
public void speak() { System.out.println("Meow!"); }
}
// 简单工厂
class AnimalFactory {
public static Animal createAnimal(String type) {
switch (type.toLowerCase()) {
case "dog": return new Dog();
case "cat": return new Cat();
default: throw new IllegalArgumentException("Unknown animal type");
}
}
}
// 客户端调用
public class Main {
public static void main(String[] args) {
Animal dog = AnimalFactory.createAnimal("dog");
dog.speak(); // 输出: Woof!
}
}
2. 工厂方法模式[编辑 | 编辑源代码]
将工厂抽象为接口,每个具体产品由对应的子工厂创建,符合开闭原则。
类图[编辑 | 编辑源代码]
代码示例[编辑 | 编辑源代码]
from abc import ABC, abstractmethod
# 产品接口
class Button(ABC):
@abstractmethod
def render(self): pass
# 具体产品
class WindowsButton(Button):
def render(self): return "Windows风格按钮"
class MacOSButton(Button):
def render(self): return "MacOS风格按钮"
# 工厂接口
class GUIFactory(ABC):
@abstractmethod
def create_button(self) -> Button: pass
# 具体工厂
class WindowsFactory(GUIFactory):
def create_button(self): return WindowsButton()
class MacOSFactory(GUIFactory):
def create_button(self): return MacOSButton()
# 客户端
def client_code(factory: GUIFactory):
button = factory.create_button()
print(button.render())
client_code(WindowsFactory()) # 输出: Windows风格按钮
3. 抽象工厂模式[编辑 | 编辑源代码]
用于创建相关或依赖对象的家族,而不需指定具体类。适合处理多个产品等级结构。
实际案例:跨平台UI组件[编辑 | 编辑源代码]
应用场景[编辑 | 编辑源代码]
- 框架设计:如Spring的BeanFactory
- 数据库连接:不同数据库驱动创建
- 游戏开发:不同角色/道具的生成
- 跨平台应用:如上述UI组件案例
优缺点对比[编辑 | 编辑源代码]
类型 | 优点 | 缺点 |
---|---|---|
简单工厂 | 实现简单,快速隔离创建逻辑 | 违反开闭原则(需修改工厂代码) |
工厂方法 | 符合开闭原则,扩展性强 | 类数量增加 |
抽象工厂 | 能创建产品家族,保证兼容性 | 结构复杂,难以支持新种类产品 |
数学关系[编辑 | 编辑源代码]
工厂模式可视为一个映射函数: 其中:
- 是输入参数(如字符串、枚举)
- 是实现了统一接口的对象
常见面试问题[编辑 | 编辑源代码]
1. 工厂方法与抽象工厂的核心区别是什么? 2. 如何避免简单工厂的switch-case带来的维护问题? 3. 举例说明哪些开源库使用了工厂模式?