工厂模式 (Factory Method)全面讲解
学习笔记
设计模式
工厂方法模式
软件开发
面向对象编程
Java
代码设计
本文详细介绍了工厂方法模式的概念、优势、结构以及示例代码,适合软件开发者学习面向对象设计原则和代码设计模式。
工厂方法模式 (Factory Method) 全面讲解
1. 什么是工厂方法模式?
工厂方法模式定义了一个创建对象的接口,但由子类决定实例化哪个类。
- 核心思想:将对象的创建延迟到子类,解决直接
new带来的耦合问题。 - 类比:餐厅点餐,菜单是接口,具体菜品由后厨(子类)决定。
2. 为什么需要工厂方法模式?
直接new的问题:
// 硬编码创建对象,紧耦合!
Car car = new Tesla();
// 如果想换成比亚迪,需要修改代码:
Car car = new BYD();
- 缺点:违反开闭原则(对扩展开放,对修改关闭)。
工厂方法的优势:
// 通过工厂创建,客户端代码无需修改
Car car = CarFactory.createCar();
- 解耦:客户端代码和具体类分离。
- 扩展性:新增车型只需扩展工厂子类。
3. 工厂方法模式的结构
角色:
Product(抽象产品):定义对象的接口(如Car)。ConcreteProduct(具体产品):实现抽象产品(如Tesla、BYD)。Creator(抽象工厂):声明工厂方法(如CarFactory)。ConcreteCreator(具体工厂):实现工厂方法(如TeslaFactory)。
3.1 示例代码(汽车工厂)
步骤1:定义抽象产品
public interface Car {
void drive();
}
步骤2:定义具体产品
public class Tesla implements Car {
@Override
public void drive() {
System.out.println("驾驶特斯拉");
}
}
public class BYD implements Car {
@Override
public void drive() {
System.out.println("驾驶比亚迪");
}
}
步骤3:定义抽象工厂
public interface CarFactory {
Car createCar(); // 工厂方法
}
步骤4:定义具体工厂
public class TeslaFactory implements CarFactory {
@Override
public Car createCar() {
return new Tesla();
}
}
public class BYDFactory implements CarFactory {
@Override
public Car createCar() {
return new BYD();
}
}
步骤5:客户端调用
public class Client {
public static void main(String[] args) {
CarFactory factory = new TeslaFactory(); // 切换工厂即可换产品
Car car = factory.createCar();
car.drive(); // 输出:驾驶特斯拉
}
}
4. 工厂方法 vs 简单工厂
简单工厂(非标准模式)
public class SimpleCarFactory {
public static Car createCar(String type) {
if ("Tesla".equals(type)) {
return new Tesla();
} else if ("BYD".equals(type)) {
return new BYD();
}
throw new IllegalArgumentException("未知车型");
}
}
- 缺点:违反开闭原则(新增车型需修改工厂类)。
工厂方法(标准模式)
- 优点:新增车型只需新增工厂子类(如
AudiFactory),无需修改原有代码。
5. 应用场景
- 经典用途:
- 日志框架(如
Log4j的LoggerFactory)。 - JDBC的
Connection(不同数据库驱动)。
- 日志框架(如
- 面试考点:
- 工厂方法与抽象工厂的区别(前者生产一种产品,后者生产产品族)。
6. 互动实践
问题1:以下代码违反了什么原则?如何改进?
public class CarFactory {
public Car createCar(String brand) {
if ("Tesla".equals(brand)) {
return new Tesla();
} else if ("BYD".equals(brand)) {
return new BYD();
}
return null;
}
}
- 答案:违反开闭原则。改进方式:使用工厂方法模式,为每个品牌创建独立工厂类。
问题2:用工厂方法实现一个PizzaStore
// 你的任务:补全Pizza工厂方法模式
public interface Pizza {
void bake();
}
public class MargheritaPizza implements Pizza { /*...*/ }
public class PepperoniPizza implements Pizza { /*...*/ }
public interface PizzaFactory {
Pizza createPizza();
}
public class MargheritaFactory implements PizzaFactory { /*...*/ }
// 补全PepperoniFactory和客户端调用代码
7. 考试练习题
题目1(概念题)
工厂方法模式的目的是什么?
A. 封装对象的创建过程
B. 强制使用继承
C. 减少类的数量
D. 替代多态
答案:A
题目2(代码填空)
补全以下工厂方法模式的代码:
public interface Document {
void open();
}
public class WordDocument implements Document {
@Override
public void open() { System.out.println("打开Word"); }
}
public interface DocumentFactory {
____ createDocument(); // 填空1
}
public class WordFactory implements DocumentFactory {
@Override
public ____ createDocument() { // 填空2
return ____; // 填空3
}
}
答案:
DocumentDocumentnew WordDocument()
题目3(设计题)
如何用工厂方法模式设计一个跨平台UI组件(如Button)?画出类图并说明。
答案:
- 抽象产品:
Button接口(含render()方法)。 - 具体产品:
WindowsButton、MacButton。 - 抽象工厂:
ButtonFactory接口。 - 具体工厂:
WindowsButtonFactory、MacButtonFactory。